Index: trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/BiosFile.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/BiosFile.asm	(revision 588)
+++ trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/BiosFile.asm	(revision 589)
@@ -75,6 +75,6 @@
 
 	cmp		dx, MAX_EEPROM_SIZE_IN_BYTES >> 16
+	jb		SHORT .FileNotTooBig
 	ja		SHORT .FileTooBig
-	jb		SHORT .FileNotTooBig
 	cmp		ax, MAX_EEPROM_SIZE_IN_BYTES & 0FFFFh
 	ja		SHORT .FileTooBig
Index: trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Buffers.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Buffers.asm	(revision 588)
+++ trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Buffers.asm	(revision 589)
@@ -214,13 +214,28 @@
 	call	Buffers_GetFileBufferToESDI
 	call	EEPROM_GetXtideUniversalBiosSizeFromESDItoDXCX
-	dec		cx				; Leave space for checksum byte
-	xor		ax, ax
-ALIGN JUMP_ALIGN
+
+; Compatibility fix for 3Com 3C503 cards where the ASIC returns 8080h as the last two bytes of the ROM.
+
+	; Assume the BIOS size is not 8K, ie generate a normal checksum.
+	dec		cx
+	mov		ax, 100h
+	cmp		cx, 8192 - 1
+	jne		SHORT .BiosSizeIsNot8K
+	; The BIOS size is 8K and therefore a potential candidate for a 3Com 3C503 card.
+	dec		cx
+	dec		cx
+	mov		ah, 3
+ALIGN JUMP_ALIGN
+.BiosSizeIsNot8K:
 .SumNextByte:
 	add		al, [es:di]
+.NextChecksumByte:
 	inc		di
 	loop	.SumNextByte
 	neg		al
 	mov		[es:di], al
+	inc		cx
+	dec		ah
+	jnz		SHORT .NextChecksumByte
 
 	pop		dx
@@ -271,19 +286,20 @@
 ;		ES:DI:	Ptr to file buffer
 ;	Corrupts registers:
-;		AX
+;		Nothing
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
 Buffers_GetIdeControllerCountToCX:
-	call	Buffers_GetFileBufferToESDI
-	mov		al, [es:di+ROMVARS.bIdeCnt]
-
-	; Limit controller count for lite mode
+	xor		cx, cx
+	call	Buffers_GetFileBufferToESDI
+	or		cl, [es:di+ROMVARS.bIdeCnt]
+	jnz		SHORT .LimitControllerCountForLiteMode
+	inc		cx				; Make sure there is at least one controller
+
+.LimitControllerCountForLiteMode:
 	test	BYTE [es:di+ROMVARS.wFlags], FLG_ROMVARS_FULLMODE
 	jnz		SHORT .ReturnControllerCountInCX
-	MIN_U	al, MAX_LITE_MODE_CONTROLLERS
+	MIN_U	cl, MAX_LITE_MODE_CONTROLLERS
 
 .ReturnControllerCountInCX:
-	cbw		; A maximum of 127 controllers should be sufficient
-	xchg	cx, ax
 	ret
 
Index: trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/EEPROM.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/EEPROM.asm	(revision 588)
+++ trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/EEPROM.asm	(revision 589)
@@ -81,4 +81,5 @@
 	mov		cl, dl
 	eSHL_IM	ch, 1
+	eRCL_IM	dl, 1
 	ret
 
Index: trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/IdeAutodetect.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/IdeAutodetect.asm	(revision 588)
+++ trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/IdeAutodetect.asm	(revision 589)
@@ -56,5 +56,5 @@
 DetectMemoryMappedDeviceFromSegmentDX:
 	; *** Try to detect JR-IDE/ISA and ADP50L (only if MODULE_8BIT_IDE_ADVANCED is present) ***
-	test	WORD [di+ROMVARS.wFlags], FLG_ROMVARS_MODULE_8BIT_IDE_ADVANCED
+	test	BYTE [di+ROMVARS.wFlags], FLG_ROMVARS_MODULE_8BIT_IDE_ADVANCED
 	stc
 	jz		SHORT .NoIdeDeviceFound
Index: trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Main.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Main.asm	(revision 588)
+++ trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Main.asm	(revision 589)
@@ -76,19 +76,29 @@
 ALIGN JUMP_ALIGN
 Main_Start:
+	mov		ah, GET_DOS_VERSION
+	int		DOS_INTERRUPT_21h
+	cmp		al, 2
+	jae		SHORT .DosVersionIsOK
+	mov		dx, g_s$NotMinimumDosVersion
+	mov		ah, WRITE_STRING_TO_STANDARD_OUTPUT
+	int		DOS_INTERRUPT_21h
+	ret
+.DosVersionIsOK:
+
 	mov		ax, SCREEN_BACKGROUND_CHARACTER_AND_ATTRIBUTE
-	call	InitializeScreenWithBackgroudCharAndAttrInAX
+	call	InitializeScreenWithBackgroundCharAndAttrInAX
 
 	call	Main_InitializeCfgVars
 	call	MenuEvents_DisplayMenu
 	mov		ax, DOS_BACKGROUND_CHARACTER_AND_ATTRIBUTE
-	call	InitializeScreenWithBackgroudCharAndAttrInAX
+	call	InitializeScreenWithBackgroundCharAndAttrInAX
 
 	; Exit to DOS
-	mov 	ax, 4C00h			; Exit to DOS
-	int 	21h
+	mov 	ax, TERMINATE_WITH_RETURN_CODE<<8		; Errorlevel 0 in AL
+	int		DOS_INTERRUPT_21h
 
 
 ;--------------------------------------------------------------------
-; InitializeScreenWithBackgroudCharAndAttrInAX
+; InitializeScreenWithBackgroundCharAndAttrInAX
 ;	Parameters:
 ;		AL:		Background character
@@ -100,5 +110,5 @@
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
-InitializeScreenWithBackgroudCharAndAttrInAX:
+InitializeScreenWithBackgroundCharAndAttrInAX:
 	xchg	dx, ax
 	CALL_DISPLAY_LIBRARY InitializeDisplayContext	; Reset cursor etc
Index: trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/MenuitemPrint.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/MenuitemPrint.asm	(revision 588)
+++ trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/MenuitemPrint.asm	(revision 589)
@@ -156,4 +156,5 @@
 ; MenuitemPrint_WriteLookupValueStringToBufferInESDIfromUnshiftedItemInDSSI
 ; MenuitemPrint_WriteLookupValueStringToBufferInESDIfromShiftedItemInDSSI
+; MenuitemPrint_WriteLookupValueStringToBufferInESDIfromRawItemInDSSI
 ;	Parameters:
 ;		DS:SI:	Ptr to MENUITEM
@@ -177,5 +178,5 @@
 
 ;--------------------------------------------------------------------
-; MenuitemPrint_WriteLookupValueStringToBufferInESDIfromItemInDSSI
+; PrintLookupValueFromAXtoBufferInESDI
 ;	Parameters:
 ;		AX:		Value to print
@@ -190,12 +191,12 @@
 PrintLookupValueFromAXtoBufferInESDI:
 	push	si
-	test	byte [si+MENUITEM.bFlags], FLG_MENUITEM_CHOICESTRINGS
-	jnz		.lookupChoice
+	test	BYTE [si+MENUITEM.bFlags], FLG_MENUITEM_CHOICESTRINGS
+	jnz		SHORT .LookupChoice
 
 	add		ax, [si+MENUITEM.itemValue+ITEM_VALUE.rgszValueToStringLookup]
 	xchg	bx, ax
-.found:
+.Found:
 	mov		si, [bx]
-.errorReturn:
+.ErrorReturn:
 	call	String_CopyDSSItoESDIandGetLengthToCX
 	pop		si
@@ -212,20 +213,20 @@
 ; value could be zero, we don't use the .rgwChoiceToValueLookup array to find the end.
 ;
-.lookupChoice:
-	mov		bx,[si+MENUITEM.itemValue+ITEM_VALUE.rgszChoiceToStringLookup]
-	mov		si,[si+MENUITEM.itemValue+ITEM_VALUE.rgwChoiceToValueLookup]
-
-.wordLoop:
-	cmp		ax,[si]
-	jz		.found
+.LookupChoice:
+	mov		bx, [si+MENUITEM.itemValue+ITEM_VALUE.rgszChoiceToStringLookup]
+	mov		si, [si+MENUITEM.itemValue+ITEM_VALUE.rgwChoiceToValueLookup]
+
+.WordLoop:
+	cmp		ax, [si]
+	je		SHORT .Found
 	inc		bx
 	inc		bx
 	inc		si
 	inc		si
-	cmp		word [bx],0
-	jnz		.wordLoop
-
-	mov		si,g_szValueUnknownError
-	jmp		.errorReturn
+	cmp		WORD [bx], 0
+	jne		SHORT .WordLoop
+
+	mov		si, g_szValueUnknownError
+	jmp		SHORT .ErrorReturn
 
 ;--------------------------------------------------------------------
Index: trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Menupages/ConfigurationMenu.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Menupages/ConfigurationMenu.asm	(revision 588)
+++ trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Menupages/ConfigurationMenu.asm	(revision 589)
@@ -177,5 +177,6 @@
 		%assign i i+1
 	%endrep
-	;	dw	NULL	; Is this needed? *FIXME*
+		dw	NULL
+
 
 ; Section containing code
@@ -285,5 +286,5 @@
 	call	Buffers_GetRomvarsFlagsToAX
 	mov		bx, g_MenuitemConfigurationIdleTimeout
-	test	ax, FLG_ROMVARS_MODULE_POWER_MANAGEMENT
+	test	al, FLG_ROMVARS_MODULE_POWER_MANAGEMENT
 	jz		SHORT .DisableMenuitemFromCSBX
 	; Fall to .EnableMenuitemFromCSBX
@@ -393,7 +394,5 @@
 	push	es
 	pop		ds
-	xor		ch, ch						; clearing high order of CX and notification flag
-	mov		dx, cx						; (probably unnecessary, CX should be less than 127, but just to be sure)
-	jcxz	.done						; probably unnecessary, but make sure there is at least one controller
+	mov		dx, cx						; Controller count to DL (will always be at least 1) while also clearing notification flag in DH
 
 	lea		bx, [di+ROMVARS.ideVars0]	; add in offset of first idevars
@@ -404,12 +403,11 @@
 	xor		ax, ax						; first non-serial found
 	mov		cl, dl						; idevars count
-	xor		ch, ch
 
 .loop:
-	cmp		byte [di+IDEVARS.bDevice], DEVICE_SERIAL_PORT
-	jnz		.notSerial
+	cmp		BYTE [di+IDEVARS.bDevice], DEVICE_SERIAL_PORT
+	jne		SHORT .notSerial
 
 	test	si, si						; record the first serial controller that we find
-	jnz		.next
+	jnz		SHORT .next
 	mov		si, di
 	SKIP2B	f
@@ -423,7 +421,7 @@
 
 	test	si, si						; no serial drives, nothing to do
-	jz		.done
+	jz		SHORT .done
 	cmp		si, ax						; serial port is already later on the list than any other controllers
-	ja		.done						; (also takes care of the case where there are no other controllers)
+	ja		SHORT .done					; (also takes care of the case where there are no other controllers)
 
 ;
@@ -438,9 +436,14 @@
 	mov		di, sp
 
-	mov		cx, IDEVARS_size
 	push	ss
 	pop		es
 
+%if IDEVARS_size & 1
+	mov		cl, IDEVARS_size
 	rep	movsb
+%else
+	mov		cl, IDEVARS_size / 2
+	rep movsw
+%endif
 
 	lea		di, [si-IDEVARS_size]		; move up all the idevars below the serial, by one slot
@@ -457,8 +460,13 @@
 	push	ss
 	pop		ds
-	mov		cx, IDEVARS_size
 	; di is already at last IDEVARS position
 
+%if IDEVARS_size & 1
+	mov		cl, IDEVARS_size
 	rep	movsb
+%else
+	mov		cl, IDEVARS_size / 2
+	rep movsw
+%endif
 
 	add		sp, IDEVARS_size
@@ -469,5 +477,5 @@
 	mov		dh, 1						; set flag that we have done a relocation
 
-	jmp		.outerLoop
+	jmp		SHORT .outerLoop
 
 .done:
@@ -478,5 +486,5 @@
 
 	test	dh, dh
-	jz		.noWorkDone
+	jz		SHORT .noWorkDone
 
 	mov		dx, g_szSerialMoved
Index: trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Menupages/FlashMenu.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Menupages/FlashMenu.asm	(revision 588)
+++ trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Menupages/FlashMenu.asm	(revision 589)
@@ -328,6 +328,6 @@
 	call	.GetSelectedEepromSizeInWordsToAX
 	xor		dx, dx
-	shl		ax, 1		; Size in bytes to...
-	rcl		dx, 1		; ...DX:AX
+	eSHL_IM	ax, 1		; Size in bytes to...
+	eRCL_IM	dx, 1		; ...DX:AX
 
 	cmp		WORD [si+FLASHVARS.wEepromPageSize], BYTE 1
Index: trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Menupages/IdeControllerMenu.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Menupages/IdeControllerMenu.asm	(revision 588)
+++ trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Menupages/IdeControllerMenu.asm	(revision 589)
@@ -571,8 +571,4 @@
 
 
-;
-; No change to Device byte, but use this opportunity to change defaults stored in wPort and wPortCtrl if we are
-; changing in/out of a Serial device (since we use these bytes in radically different ways).
-;
 ALIGN JUMP_ALIGN
 IdeControllerMenu_WriteDevice:
@@ -581,10 +577,71 @@
 	push	ax
 
+	mov		bl, [es:di]							; What is the current Device we are changing from?
+	sub		di, BYTE IDEVARS.bDevice - IDEVARS.wBasePort	; Get ready to set the Port addresses
+
 	; Note! AL is the choice index, not device code
-	shl		ax, 1								; Selection to device code
-	mov		bl, [es:di]							; what is the current Device we are changing from?
-	sub		di, BYTE IDEVARS.bDevice - IDEVARS.wBasePort	; Get ready to set the Port addresses
+	shl		al, 1								; Selection to device code
+
+	; Restore ports and other stuff to default values
+	jz		SHORT .StandardIdeDevice			; DEVICE_16BIT_ATA
+
+	cmp		al, DEVICE_8BIT_ATA
+	ja		SHORT .NotStandardIdeDevice
+	jb		SHORT .AdvancedAtaDevice			; DEVICE_32BIT_ATA
+	test	BYTE [es:ROMVARS.wFlags], FLG_ROMVARS_MODULE_8BIT_IDE
+	jmp		SHORT .CheckZF
+
+.AdvancedAtaDevice:
+	test	BYTE [es:ROMVARS.wFlags+1], FLG_ROMVARS_MODULE_ADVANCED_ATA >> 8
+.CheckZF:
+	jz		SHORT .SupportForDeviceNotAvailable
+
+	; Standard ATA controllers, including 8-bit mode
+.StandardIdeDevice:
+	lea		ax, [di-ROMVARS.ideVars0+IDEVARS.wBasePort]
+	mov		bl, IDEVARS_size
+	div		bl
+	mov		bx, .rgbLowByteOfStdIdeInterfacePorts
+	xlat
+	mov		ah, 1								; DEVICE_ATA_*_PORT >> 8
+	mov		bh, 3								; DEVICE_ATA_*_PORTCTRL >> 8
+	mov		bl, al
+	jmp		SHORT .WriteNonSerial
+
+.rgbLowByteOfStdIdeInterfacePorts:				; Defaults for 16-bit and better ATA devices
+	db		DEVICE_ATA_PRIMARY_PORT		& 0FFh
+	db		DEVICE_ATA_SECONDARY_PORT	& 0FFh
+	db		DEVICE_ATA_TERTIARY_PORT	& 0FFh
+	db		DEVICE_ATA_QUATERNARY_PORT	& 0FFh
+
+.NotStandardIdeDevice:
 	cmp		al, DEVICE_SERIAL_PORT
-	je		SHORT .ChangingToSerial
+	jb		SHORT .NotSerialDevice
+	test	BYTE [es:ROMVARS.wFlags+1], FLG_ROMVARS_MODULE_SERIAL >> 8
+	jnz		SHORT .ChangingToSerial
+
+.SupportForDeviceNotAvailable:
+	push	dx
+	mov		dx, g_szUnsupportedDevice
+	call	Dialogs_DisplayErrorFromCSDX
+	pop		dx
+
+	; Restore device type to the previous value
+	pop		ax									; Get choice index from stack
+	mov		al, bl								; Previous device type to AL
+	shr		al, 1								; Device code to choice index
+	jmp		SHORT .DoneWithNoChangeOfDevice
+
+.NotSerialDevice:
+	; Remaining device types all require MODULE_8BIT_IDE or MODULE_8BIT_IDE_ADVANCED
+	test	BYTE [es:ROMVARS.wFlags], FLG_ROMVARS_MODULE_8BIT_IDE | FLG_ROMVARS_MODULE_8BIT_IDE_ADVANCED
+	jz		SHORT .SupportForDeviceNotAvailable
+
+	; We know MODULE_8BIT_IDE is included
+	lahf	; Save the PF
+	cmp		al, DEVICE_8BIT_XTIDE_REV2
+	jbe		SHORT .ChangingToXTIDEorXTCF
+	sahf	; Restore the PF
+	jpo		SHORT .SupportForDeviceNotAvailable	; Jump if no MODULE_8BIT_IDE_ADVANCED
 	cmp		al, DEVICE_8BIT_JRIDE_ISA
 	je		SHORT .ChangingToJrIdeIsa
@@ -592,10 +649,5 @@
 	je		SHORT .ChangingToADP50L
 
-	; Restore ports to default values
-	cmp		al, DEVICE_8BIT_ATA					; Standard ATA controllers, including 8-bit mode
-	mov		ax, DEVICE_ATA_PRIMARY_PORT			; Defaults for 16-bit and better ATA devices
-	mov		bx, DEVICE_ATA_PRIMARY_PORTCTRL
-	jbe		SHORT .WriteNonSerial
-
+.ChangingToXTIDEorXTCF:
 	mov		ax, DEVICE_XTIDE_DEFAULT_PORT		; Defaults for 8-bit XTIDE and XT-CF devices
 	mov		bx, DEVICE_XTIDE_DEFAULT_PORTCTRL
@@ -631,4 +683,5 @@
 .Done:
 	pop		ax
+.DoneWithNoChangeOfDevice:
 	pop		di			; IDEVARS.bDevice
 	pop		bx
Index: trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Strings.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Strings.asm	(revision 588)
+++ trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Strings.asm	(revision 589)
@@ -21,7 +21,10 @@
 SECTION .data
 
+; DOS version check
+g_s$NotMinimumDosVersion:			db	LF,"This program requires DOS version 2 or higher.",LF,"$"
+
 ; Menu title
 g_szProgramTitle:					db	"Configuration and Flashing program for XTIDE Universal BIOS v2.0.0.",LF,CR,NULL
-g_szXtideUniversalBiosSignature:	db	"XTIDE205",NULL
+g_szXtideUniversalBiosSignature:	db	FLASH_SIGNATURE,NULL
 g_szBiosIsNotLoaded:				db	"BIOS is not loaded!",NULL
 g_szEEPROM:							db	"EEPROM",NULL
@@ -134,5 +137,5 @@
 						db	" Conventional memory. This makes it possible to use ROM BASIC and other software that requires"
 						db	" the interrupt vectors where XTIDE Universal BIOS parameters would be stored in Lite mode.",LF,LF
-						db	"Lite mode supports only one IDE controller (2 drives) and stores parameters to the top of the interrupt vectors"
+						db	"Lite mode supports only 2 IDE controllers (4 drives) and stores parameters to the top of the interrupt vectors"
 						db	" (30:0h) so no Conventional memory needs to be reserved. Lite mode cannot be used if some software requires"
 						db	" the top of interrupt vectors. Usually this is not a problem since only IBM ROM BASIC uses them.",LF,LF
@@ -221,4 +224,6 @@
 g_szDlgIdeEnIRQ:			db	"Enable interrupt?",NULL
 g_szDlgIdeIRQ:				db	"Enter IRQ channel (2...7 for 8-bit controllers, 2...15 for any other controller).",NULL
+g_szUnsupportedDevice:		db	"There is no support for this device type in the currently loaded BIOS."
+							db	" You must load a BIOS built with the proper module included to be able to use this type of device.",NULL
 
 g_szNfoIdeBackToCfgMenu:	db	"Back to XTIDE Universal BIOS Configuration Menu.",NULL
@@ -275,7 +280,7 @@
 							db	"XTIDE rev 1",LF
 							db	"XTIDE rev 2 or modded rev 1",LF
-							db	"XT-CF (PIO8)",LF
-							db	"XT-CF (PIO8 w/BIU offload)",LF
-							db	"XT-CF (PIO16 w/BIU offload)",LF
+							db	"XT-CF PIO8",LF
+							db	"XT-CF PIO8 (BIU offload)",LF
+							db	"XT-CF PIO16 (BIU offload)",LF
 							db	"XT-CF DMA (v3 only)",LF
 							db	"JR-IDE/ISA",LF
