Index: trunk/XTIDE_Universal_BIOS/Inc/Controllers/PDC20x30.inc
===================================================================
--- trunk/XTIDE_Universal_BIOS/Inc/Controllers/PDC20x30.inc	(revision 621)
+++ trunk/XTIDE_Universal_BIOS/Inc/Controllers/PDC20x30.inc	(revision 622)
@@ -22,11 +22,24 @@
 %define PDC20x30_INC
 
+; 
 
-; SECTOR_COUNT_REGISTER in programming mode
-FLG_PDCSCR_UNKNOWN_BIT7		EQU		(1<<7)	; Set to 1 for speed setting 7 of device 0 or 1
-FLG_PDCSCR_ID3				EQU		(1<<6)	; VLB bus speed: 0 > 33 MHz, 1 <= 33 MHz
-POS_PDCSCR_DEV0SPEED		EQU		3
-MASK_PDCSCR_DEV0SPEED		EQU		(7<<POS_PDCSCR_DEV0SPEED)	; 0 to 7
-MASK_PDCSCR_DEV1SPEED		EQU		(7<<0)						; 0 to 7
+; SECTOR_COUNT_REGISTER (1F2) in programming mode
+FLG_PDCSCR_BOTHMAX			EQU		(1<<6)	; Master and Slave at maximum speed
+
+; SECTOR_NUMBER_REGISTER (1F3) in programming mode
+FLG_PDCSNR_UNKNOWN_BIT7		EQU		(1<<7)	; Set to 1 for speed setting 7 of device 0 or 1
+FLG_PDCSNR_ID3				EQU		(1<<6)	; VLB bus speed: 0 > 33 MHz, 1 <= 33 MHz
+POS_PDCSNR_DEV0SPEED		EQU		3
+MASK_PDCSNR_DEV0SPEED		EQU		(7<<POS_PDCSNR_DEV0SPEED)	; 0 to 7
+MASK_PDCSNR_DEV1SPEED		EQU		(7<<0)						; 0 to 7
+
+; Disassembly of VG4.BIN: (might have errors)
+; FLG_PDCSNR_UNKNOWN_BIT7 will be set if no dev1, no matter what speed 
+; FLG_PDCSNR_UNKNOWN_BIT7 will be cleared if dev1 found but no master
+; FLG_PDCSNR_UNKNOWN_BIT7 will be cleared if dev0 and dev1 speeds are both 7 !
+; FLG_PDCSNR_UNKNOWN_BIT7 will be cleared if dev 1 is 7 !
+; If dev 1 is 6 or less and dev 0 is 7, then dev0-- and set FLG_PDCSCR_UNKNOWN_BIT7
+; 
+
 
 
@@ -36,5 +49,5 @@
 FLG_PDCLCR_DEV1SPEED_BIT4	EQU		(1<<6)	; Same as above but for device 1
 FLG_PDCLCR_DEV0IORDY		EQU		(1<<5)	; Not sure about this
-FLG_PDCLCR_DEV1IORDY		EQU		(1<<4)	; Same as above but for device 15
+FLG_PDCLCR_DEV1IORDY		EQU		(1<<4)	; Same as above but for device 1
 FLG_PDCLCR_ENABLE_EXTRA_REGISTERS	EQU	(1<<3)
 
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDPT.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDPT.asm	(revision 621)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDPT.asm	(revision 622)
@@ -135,11 +135,16 @@
 	; We have detected 32-bit controller so change Device Type since
 	; it might have been set to 16-bit on IDEVARS
+	;
+	; Change to 32-bit on 386 builds only. We leave AT builds unchanged for faster troubleshooting
+	; and for uncommon systems, like IBM 486SLC2 processors that can have VLB motherboard even though
+	; the IBM 486SLC2 is externally 16-bit CPU
 .ChangeTo32bitDevice:
+%ifdef USE_386
 	mov		BYTE [di+DPT_ATA.bDevice], DEVICE_32BIT_ATA
+%endif
 .NoAdvancedControllerDetected:
 %endif	; MODULE_ADVANCED_ATA
 
-
-; End DPT
+	; End DPT
 	clc
 	ret
Index: trunk/XTIDE_Universal_BIOS/Src/Initialization/AdvancedAta/AdvAtaInit.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Initialization/AdvancedAta/AdvAtaInit.asm	(revision 621)
+++ trunk/XTIDE_Universal_BIOS/Src/Initialization/AdvancedAta/AdvAtaInit.asm	(revision 622)
@@ -182,2 +182,19 @@
 .PioTimingsLoadedToBXandCX:
 	ret
+
+
+;--------------------------------------------------------------------
+; Just a simple IN AL, DX instruction but the function call works
+; as I/O delay.
+;
+; AdvAtaInit_InWithDelay
+;	Parameters:
+;		DX:		Port to read from
+;	Returns:
+;		AL:		Byte read from port
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------	
+AdvAtaInit_InputWithDelay:
+	in		al, dx
+	ret
Index: trunk/XTIDE_Universal_BIOS/Src/Initialization/AdvancedAta/PDC20x30.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Initialization/AdvancedAta/PDC20x30.asm	(revision 621)
+++ trunk/XTIDE_Universal_BIOS/Src/Initialization/AdvancedAta/PDC20x30.asm	(revision 622)
@@ -53,4 +53,8 @@
 ;--------------------------------------------------------------------
 GetPdcIDtoAX:
+;Force ID_PDC20230 instead of PDC20630 detection
+;mov	ax, ID_PDC20230<<8
+;jmp		SHORT DisablePdcProgrammingMode
+
 	push	dx
 
@@ -87,7 +91,20 @@
 ;--------------------------------------------------------------------
 DisablePdcProgrammingMode:
-	add		dx, BYTE HIGH_CYLINDER_REGISTER
+	add		dx, BYTE HIGH_CYLINDER_REGISTER	; 1F5h
 	in		al, dx
 	add		dx, -HIGH_CYLINDER_REGISTER		; Sets CF for PDC20x30_DetectControllerForIdeBaseInBX
+%if 0
+	; Disassembly of VG4.BIN shows that bit 7 (programming mode activated)
+	; is cleared manually after reading from HIGH_CYLINDER_REGISTER
+	; That does not seem to be necessary.
+	inc		dx
+	inc		dx
+	call	AdvAtaInit_InputWithDelay
+	and		al, 7Fh
+	out		dx, al
+	dec		dx
+	dec		dx
+	stc
+%endif
 .Return:
 	ret
@@ -108,24 +125,29 @@
 	inc		dx
 	inc		dx
-	in		al, dx	; 1F2h (SECTOR_COUNT_REGISTER)
+	call	AdvAtaInit_InputWithDelay	; 1F2h (SECTOR_COUNT_REGISTER)
 	or		al, 80h
 	out		dx, al
 
-	; PDC detection sequence (should delay be added between register reads?)
-	add		dx, BYTE HIGH_CYLINDER_REGISTER - SECTOR_COUNT_REGISTER
-	in		al, dx	; 1F5h
+	; PDC detection sequence
+	add		dx, BYTE HIGH_CYLINDER_REGISTER - SECTOR_COUNT_REGISTER	; 5 - 2
 	cli
+	call	AdvAtaInit_InputWithDelay	; 1F5
+
 	sub		dx, BYTE HIGH_CYLINDER_REGISTER - SECTOR_COUNT_REGISTER
-	in		al, dx	; 1F2h
-	add		dx, STANDARD_CONTROL_BLOCK_OFFSET + (ALTERNATE_STATUS_REGISTER_in - SECTOR_COUNT_REGISTER)
-	in		al, dx	; 3F6h
-	in		al, dx	; 3F6h
+	call	AdvAtaInit_InputWithDelay	; 1F2h
+
+	add		dx, STANDARD_CONTROL_BLOCK_OFFSET + (ALTERNATE_STATUS_REGISTER_in - SECTOR_COUNT_REGISTER)	; 200h+(6-2)
+	call	AdvAtaInit_InputWithDelay	; 3F6h
+
+	call	AdvAtaInit_InputWithDelay	; 3F6h
+
 	sub		dx, STANDARD_CONTROL_BLOCK_OFFSET + (ALTERNATE_STATUS_REGISTER_in - SECTOR_COUNT_REGISTER)
-	in		al, dx	; 1F2h
-	in		al, dx	; 1F2h
+	call	AdvAtaInit_InputWithDelay	; 1F2h
+
+	call	AdvAtaInit_InputWithDelay	; 1F2h
 	sti
 
 	; PDC20230C and PDC20630 clears the bit we set at the beginning
-	in		al, dx	; 1F2h
+	call	AdvAtaInit_InputWithDelay	; 1F2h
 	dec		dx
 	dec		dx		; Base port
@@ -186,4 +208,9 @@
 	jne		SHORT .InitializationCompleted
 	call	SetPdc20630SpeedForDriveInCX
+
+	; TODO: Should we first call SetPdc20630SpeedForDriveInCX and then
+	; force SetSpeedForDriveInCX to PIO 0 (maximum speed setting 8)?
+	; Need to test with PCD20630.
+
 .InitializationCompleted:
 	mov		dx, [di+DPT.wBasePort]
@@ -200,5 +227,5 @@
 ;		DS:DI:	Ptr to DPT
 ;	Returns:
-;		DX:		Sector Number Register
+;		DX:		Sector Number Register (1F3h)
 ;	Corrupts registers:
 ;		AX, BX
@@ -211,19 +238,68 @@
 	xchg	bx, ax
 
-	add		dx, BYTE SECTOR_NUMBER_REGISTER
-	mov		bh, ~MASK_PDCSCR_DEV1SPEED	; Assume slave
+	add		dx, BYTE SECTOR_NUMBER_REGISTER	; 1F3h
+	mov		bh, ~MASK_PDCSNR_DEV1SPEED		; Assume slave
 	inc		cx
+	mov		ah, 7	; Max speed value. Set unknown bit 7 if either of drives are set to this
 	loop	.SetSpeed
-	eSHL_IM	bl, POS_PDCSCR_DEV0SPEED
-	mov		bh, ~MASK_PDCSCR_DEV0SPEED
+	mov		ah, 7 << POS_PDCSNR_DEV0SPEED
+	eSHL_IM	bl, POS_PDCSNR_DEV0SPEED
+	mov		bh, ~MASK_PDCSNR_DEV0SPEED
 .SetSpeed:
 	in		al, dx
 	and		al, bh
 	or		al, bl
-	cmp		bl, 7
+	cmp		bl, ah
 	jb		SHORT .OutputNewValue
-	or		al, FLG_PDCSCR_UNKNOWN_BIT7	; Flag for PIO 2 and above?
+	or		al, FLG_PDCSNR_UNKNOWN_BIT7		; Flag for PIO 2 and above?
 .OutputNewValue:
 	out		dx, al
+
+	; The above speed set does not work with Octek VL-COMBO rev 3.2 with PDC20230C
+	; Only thing to make it work is to set FLG_PDCSCR_BOTHMAX to 1F2h. Are all PDC20230C controllers
+	; like that? If so, why the above speed is not set? Or does the VL-COMBO or other PDC20230C
+	; controllers have a jumper to prevent speed setup by software? (PDC20230B can only be set
+	; by hardware, for example), like pin-compatible operation with older PDC20230B, perhaps?
+	; Datasheets would be very useful...
+	; For now, we just set the FLG_PDCSCR_BOTHMAX bit if either of the drives are set to speed 7
+	;
+	; Code below is not perfect. It does not properly test if both drives support PIO 2 but
+	; likely if slave does, so does master (and if slave does not, we clear the
+	; FLG_PDCSCR_BOTHMAX set by master)
+	mov		bl, 1	; Set bit 0, see VG4.BIN comments below
+	test	al, al
+	jns		SHORT .DoNotSetMaxSpeedBit
+	or		bl, FLG_PDCSCR_BOTHMAX
+.DoNotSetMaxSpeedBit:
+	dec		dx		; SECTOR_COUNT_REGISTER, 1F2h
+	call	AdvAtaInit_InputWithDelay
+	and		al, ~FLG_PDCSCR_BOTHMAX
+	or		al, bl
+	out		dx, al
+
+	; VG4.BIN ("External BIOS") does the following after programming speed (1F3h)
+	; (It never seems to set the speed bit we just set above).
+	; The below code does not seem to have any effect, at least not for PDC20230C.
+	; Why is bit 0 set to 1F2h?
+	; Is it just to keep programming mode active if it has timeout, for example?
+	; But after all that it just reads 1F5h to disable programming mode.
+%if 0
+	; Test code start
+	push	cx
+	mov		cx, 100
+	DELAY_WITH_LOOP_INSTRUCTION_NA
+
+	; Does below tell the controller that new speed is set?
+	in		al, dx
+	or		al, 1
+	out		dx, al
+
+	mov		cx, 100
+	DELAY_WITH_LOOP_INSTRUCTION_NA
+	pop		cx
+	; Test code end
+%endif
+
+	inc		dx		; SECTOR_NUMBER_REGISTER, 1F3h
 	ret
 
@@ -239,5 +315,5 @@
 ;		CX:		0 for master, 1 for slave drive
 ;		DS:DI:	Ptr to DPT
-;		DX:		Sector Number Register
+;		DX:		Sector Number Register, 1F3h
 ;	Returns:
 ;		DX:		Low Cylinder Register
Index: trunk/XTIDE_Universal_BIOS/makefile
===================================================================
--- trunk/XTIDE_Universal_BIOS/makefile	(revision 621)
+++ trunk/XTIDE_Universal_BIOS/makefile	(revision 622)
@@ -134,5 +134,5 @@
 BIOS_SIZE_TINY = 4096
 BIOS_SIZE_SMALL = 8192
-BIOS_SIZE_LARGE = 10240
+BIOS_SIZE_LARGE = 12288
 BIOS_SIZE_CUSTOM = ?
 
