Index: trunk/XTIDE_Universal_BIOS/Src/Device/Device.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/Device.asm	(revision 234)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/Device.asm	(revision 238)
@@ -4,4 +4,23 @@
 ; Section containing code
 SECTION .text
+
+
+%macro TEST_USIGN_DPT_AND_JUMP_IF_SERIAL_DEVICE 1
+	test	BYTE [di+DPT.bFlagsHigh], FLGH_DPT_SERIAL_DEVICE
+	jnz		SHORT %1
+%endmacro
+
+%macro CMP_USING_DPT_AND_JUMP_IF_JRIDE_DEVICE 1
+	eMOVZX	bx, [di+DPT.bIdevarsOffset]
+	cmp		BYTE [cs:bx+IDEVARS.bDevice], DEVICE_JRIDE_ISA
+	je		SHORT %1
+%endmacro
+
+%macro CMP_USING_IDEVARS_IN_CSBP_AND_JUMP_IF 2
+	cmp		BYTE [cs:bp+IDEVARS.bDevice], %1
+	je		SHORT %2
+%endmacro
+
+
 
 ;--------------------------------------------------------------------
@@ -18,11 +37,10 @@
 %ifdef MODULE_SERIAL
 Device_FinalizeDPT:
-	test	BYTE [di+DPT.bFlagsHigh], FLGH_DPT_SERIAL_DEVICE
-	jnz		SHORT .FinalizeDptForSerialPortDevice
+	TEST_USIGN_DPT_AND_JUMP_IF_SERIAL_DEVICE .FinalizeDptForSerialPortDevice
 	jmp		IdeDPT_Finalize
-
 .FinalizeDptForSerialPortDevice:
 	jmp		SerialDPT_Finalize
-%else
+
+%else	; IDE or JR-IDE/ISA
 	Device_FinalizeDPT EQU IdeDPT_Finalize
 %endif
@@ -39,11 +57,29 @@
 ;		AL, BX, CX, DX
 ;--------------------------------------------------------------------
-%ifdef MODULE_SERIAL
+%ifdef MODULE_JRIDE
+	%ifdef MODULE_SERIAL				; IDE + JR-IDE/ISA + Serial
+	Device_ResetMasterAndSlaveController:
+		TEST_USIGN_DPT_AND_JUMP_IF_SERIAL_DEVICE ReturnSuccessForSerialPort
+		CMP_USING_DPT_AND_JUMP_IF_JRIDE_DEVICE .ResetJrIDE
+		jmp		IdeCommand_ResetMasterAndSlaveController
+
+	%else								; IDE + JR-IDE/ISA
+	Device_ResetMasterAndSlaveController:
+		CMP_USING_DPT_AND_JUMP_IF_JRIDE_DEVICE .ResetJrIDE
+		jmp		IdeCommand_ResetMasterAndSlaveController
+	%endif
+
+%elifdef MODULE_SERIAL					; IDE + Serial
 Device_ResetMasterAndSlaveController:
-	test	BYTE [di+DPT.bFlagsHigh], FLGH_DPT_SERIAL_DEVICE
-	jnz		SHORT ReturnSuccessForSerialPort
+	TEST_USIGN_DPT_AND_JUMP_IF_SERIAL_DEVICE ReturnSuccessForSerialPort
 	jmp		IdeCommand_ResetMasterAndSlaveController
-%else
+
+%else									; IDE
 	Device_ResetMasterAndSlaveController EQU IdeCommand_ResetMasterAndSlaveController
+%endif
+
+%ifdef MODULE_JRIDE
+.ResetJrIDE:
+	jmp		MemIdeCommand_ResetMasterAndSlaveController
 %endif
 
@@ -62,14 +98,34 @@
 ;		AL, BL, CX, DX, SI, DI, ES
 ;--------------------------------------------------------------------
-%ifdef MODULE_SERIAL
+%ifdef MODULE_JRIDE
+	%ifdef MODULE_SERIAL				; IDE + JR-IDE/ISA + Serial
+	Device_IdentifyToBufferInESSIwithDriveSelectByteInBH:
+		CMP_USING_IDEVARS_IN_CSBP_AND_JUMP_IF DEVICE_SERIAL_PORT, .IdentifyDriveFromSerialPort
+		CMP_USING_IDEVARS_IN_CSBP_AND_JUMP_IF DEVICE_JRIDE_ISA, .IdentifyDriveFromJrIde
+		jmp		IdeCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH
+
+	%else								; IDE + JR-IDE/ISA
+	Device_IdentifyToBufferInESSIwithDriveSelectByteInBH:
+		CMP_USING_IDEVARS_IN_CSBP_AND_JUMP_IF DEVICE_JRIDE_ISA, .IdentifyDriveFromJrIde
+		jmp		IdeCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH
+	%endif
+
+%elifdef MODULE_SERIAL					; IDE + Serial
 Device_IdentifyToBufferInESSIwithDriveSelectByteInBH:
-	cmp		BYTE [cs:bp+IDEVARS.bDevice], DEVICE_SERIAL_PORT
-	je		SHORT .IdentifyDriveFromSerialPort
+	CMP_USING_IDEVARS_IN_CSBP_AND_JUMP_IF DEVICE_SERIAL_PORT, .IdentifyDriveFromSerialPort
 	jmp		IdeCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH
 
+%else									; IDE
+	Device_IdentifyToBufferInESSIwithDriveSelectByteInBH EQU IdeCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH
+%endif
+
+%ifdef MODULE_JRIDE
+.IdentifyDriveFromJrIde:
+	jmp		MemIdeCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH
+%endif
+
+%ifdef MODULE_SERIAL
 .IdentifyDriveFromSerialPort:
 	jmp		SerialCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH
-%else
-	Device_IdentifyToBufferInESSIwithDriveSelectByteInBH EQU IdeCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH
 %endif
 
@@ -89,16 +145,36 @@
 ;		AL, BX, CX, DX, (ES:SI for data transfer commands)
 ;--------------------------------------------------------------------
-%ifdef MODULE_SERIAL
-ALIGN JUMP_ALIGN
+%ifdef MODULE_JRIDE
+	%ifdef MODULE_SERIAL				; IDE + JR-IDE/ISA + Serial
+	Device_OutputCommandWithParameters:
+		TEST_USIGN_DPT_AND_JUMP_IF_SERIAL_DEVICE .OutputCommandToSerialPort
+		CMP_USING_DPT_AND_JUMP_IF_JRIDE_DEVICE .OutputCommandToJrIDE
+		jmp		IdeCommand_OutputWithParameters
+
+	%else								; IDE + JR-IDE/ISA
+	Device_OutputCommandWithParameters:
+		CMP_USING_DPT_AND_JUMP_IF_JRIDE_DEVICE .OutputCommandToJrIDE
+		jmp		IdeCommand_OutputWithParameters
+	%endif
+
+%elifdef MODULE_SERIAL					; IDE + Serial
 Device_OutputCommandWithParameters:
-	test	BYTE [di+DPT.bFlagsHigh], FLGH_DPT_SERIAL_DEVICE
-	jnz		SHORT .OutputCommandToSerialPort
+	TEST_USIGN_DPT_AND_JUMP_IF_SERIAL_DEVICE .OutputCommandToSerialPort
 	jmp		IdeCommand_OutputWithParameters
 
+%else									; IDE
+	Device_OutputCommandWithParameters EQU IdeCommand_OutputWithParameters
+%endif
+
+%ifdef MODULE_JRIDE
+ALIGN JUMP_ALIGN
+.OutputCommandToJrIDE:
+	jmp		MemIdeCommand_OutputWithParameters
+%endif
+
+%ifdef MODULE_SERIAL
 ALIGN JUMP_ALIGN
 .OutputCommandToSerialPort:
 	jmp		SerialCommand_OutputWithParameters
-%else
-	Device_OutputCommandWithParameters EQU IdeCommand_OutputWithParameters
 %endif
 
@@ -115,16 +191,36 @@
 ;		AL, BX, CX, DX
 ;--------------------------------------------------------------------
-%ifdef MODULE_SERIAL
-ALIGN JUMP_ALIGN
+%ifdef MODULE_JRIDE
+	%ifdef MODULE_SERIAL				; IDE + JR-IDE/ISA + Serial
+	Device_SelectDrive:
+		TEST_USIGN_DPT_AND_JUMP_IF_SERIAL_DEVICE ReturnSuccessForSerialPort
+		CMP_USING_DPT_AND_JUMP_IF_JRIDE_DEVICE .SelectJrIdeDrive
+		jmp		IdeCommand_SelectDrive
+
+	%else								; IDE + JR-IDE/ISA
+	Device_SelectDrive:
+		CMP_USING_DPT_AND_JUMP_IF_JRIDE_DEVICE .SelectJrIdeDrive
+		jmp		IdeCommand_SelectDrive
+	%endif
+
+%elifdef MODULE_SERIAL					; IDE + Serial
 Device_SelectDrive:
-	test	BYTE [di+DPT.bFlagsHigh], FLGH_DPT_SERIAL_DEVICE
-	jnz		SHORT ReturnSuccessForSerialPort
+	TEST_USIGN_DPT_AND_JUMP_IF_SERIAL_DEVICE ReturnSuccessForSerialPort
 	jmp		IdeCommand_SelectDrive
 
+%else									; IDE
+	Device_SelectDrive EQU IdeCommand_SelectDrive
+%endif
+
+%ifdef MODULE_JRIDE
+ALIGN JUMP_ALIGN
+.SelectJrIdeDrive:
+	jmp		MemIdeCommand_SelectDrive
+%endif
+
+%ifdef MODULE_SERIAL
+ALIGN JUMP_ALIGN
 ReturnSuccessForSerialPort:
 	xor		ax, ax
 	ret
-%else
-	Device_SelectDrive EQU IdeCommand_SelectDrive
-%endif
-
+%endif
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IOMappedIDE.inc
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IOMappedIDE.inc	(revision 238)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IOMappedIDE.inc	(revision 238)
@@ -0,0 +1,69 @@
+; Project name	:	XTIDE Universal BIOS
+; Description	:	Macros for normal I/O mapped ATA controllers.
+
+%ifndef IO_MAPPED_IDE_INC
+%define IO_MAPPED_IDE_INC
+
+;--------------------------------------------------------------------
+; OUTPUT_AL_TO_IDE_REGISTER_IN_DL
+; JUMP_TO_OUTPUT_AL_TO_IDE_REGISTER_IN_DL
+; OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER_IN_DL
+;	Parameters:
+;		AL:		Byte to output
+;		%1:		IDE Register				(OUTPUT_AL_TO_IDE_REGISTER)
+;				IDE Control Block Register	(OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER)
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		BX, DX
+;--------------------------------------------------------------------
+%macro OUTPUT_AL_TO_IDE_REGISTER 1
+%ifnidni %1, dl
+	mov		dl, %1
+%endif
+	call	IdeIO_OutputALtoIdeRegisterInDL
+%endmacro
+
+%macro JUMP_TO_OUTPUT_AL_TO_IDE_REGISTER 1
+%ifnidni %1, dl
+	mov		dl, %1
+%endif
+	jmp		IdeIO_OutputALtoIdeRegisterInDL
+%endmacro
+
+%macro OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER 1
+%ifnidni %1, dl
+	mov		dl, %1
+%endif
+	call	IdeIO_OutputALtoIdeControlBlockRegisterInDL
+%endmacro
+
+
+;--------------------------------------------------------------------
+; INPUT_TO_AL_FROM_IDE_REGISTER
+; JUMP_TO_INPUT_TO_AL_FROM_IDE_REGISTER
+;	Parameters:
+;		%1:		IDE Register
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;	Returns:
+;		AL:		Inputted byte
+;	Corrupts registers:
+;		BX, DX
+;--------------------------------------------------------------------
+%macro INPUT_TO_AL_FROM_IDE_REGISTER 1
+%ifnidni %1, dl
+	mov		dl, %1
+%endif
+	call	IdeIO_InputToALfromIdeRegisterInDL
+%endmacro
+
+%macro JUMP_TO_INPUT_TO_AL_FROM_IDE_REGISTER 1
+%ifnidni %1, dl
+	mov		dl, %1
+%endif
+	jmp		IdeIO_InputToALfromIdeRegisterInDL
+%endmacro
+
+
+%endif ; IO_MAPPED_IDE_INC
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeCommand.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeCommand.asm	(revision 234)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeCommand.asm	(revision 238)
@@ -15,10 +15,9 @@
 ;		AL, BX, CX, DX
 ;--------------------------------------------------------------------
-IdeCommand_ResetMasterAndSlaveController:
+IDEDEVICE%+Command_ResetMasterAndSlaveController:
 	; HSR0: Set_SRST
 	call	AccessDPT_GetDeviceControlByteToAL
 	or		al, FLG_DEVCONTROL_SRST | FLG_DEVCONTROL_nIEN	; Set Reset bit
-	mov		dl, DEVICE_CONTROL_REGISTER_out
-	call	IdeIO_OutputALtoIdeControlBlockRegisterInDL
+	OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER DEVICE_CONTROL_REGISTER_out
 	mov		ax, HSR0_RESET_WAIT_US
 	call	Timer_DelayMicrosecondsFromAX
@@ -28,6 +27,5 @@
 	or		al, FLG_DEVCONTROL_nIEN
 	and		al, ~FLG_DEVCONTROL_SRST						; Clear reset bit
-	mov		dl, DEVICE_CONTROL_REGISTER_out
-	call	IdeIO_OutputALtoIdeControlBlockRegisterInDL
+	OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER DEVICE_CONTROL_REGISTER_out
 	mov		ax, HSR1_RESET_WAIT_US
 	call	Timer_DelayMicrosecondsFromAX
@@ -35,5 +33,5 @@
 	; HSR2: Check_status
 	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_MOTOR_STARTUP, FLG_STATUS_BSY)
-	jmp		IdeWait_PollStatusFlagInBLwithTimeoutInBH
+	jmp		IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
 
 
@@ -51,5 +49,5 @@
 ;		AL, BL, CX, DX, SI, DI, ES
 ;--------------------------------------------------------------------
-IdeCommand_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH:
+IDEDEVICE%+Command_IdentifyDeviceToBufferInESSIwithDriveSelectByteInBH:
 	; Create fake DPT to be able to use Device.asm functions
 	call	FindDPT_ForNewDriveToDSDI
@@ -66,5 +64,5 @@
 	jnz		SHORT .SkipLongWaitSinceDriveIsNotPrimaryMaster
 	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_MOTOR_STARTUP, FLG_STATUS_BSY)
-	call	IdeWait_PollStatusFlagInBLwithTimeoutInBH
+	call	IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
 .SkipLongWaitSinceDriveIsNotPrimaryMaster:
 
@@ -100,9 +98,9 @@
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
-IdeCommand_OutputWithParameters:
+IDEDEVICE%+Command_OutputWithParameters:
 	push	bx						; Store status register bits to poll
 
 	; Select Master or Slave drive and output head number or LBA28 top bits
-	call	IdeCommand_SelectDrive
+	call	IDEDEVICE%+Command_SelectDrive
 	jc		SHORT .DriveNotReady
 
@@ -119,11 +117,9 @@
 	pop		ds
 .DoNotSetInterruptInServiceFlag:
-	mov		dl, DEVICE_CONTROL_REGISTER_out
-	call	IdeIO_OutputALtoIdeControlBlockRegisterInDL
+	OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER DEVICE_CONTROL_REGISTER_out
 
 	; Output Feature Number
-	mov		dl, FEATURES_REGISTER_out
 	mov		al, [bp+IDEPACK.bFeatures]
-	call	IdeIO_OutputALtoIdeRegisterInDL
+	OUTPUT_AL_TO_IDE_REGISTER FEATURES_REGISTER_out
 
 	; Output Sector Address High (only used by LBA48)
@@ -138,23 +134,22 @@
 
 	; Output command
-	mov		dl, COMMAND_REGISTER_out
 	mov		al, [bp+IDEPACK.bCommand]
-	call	IdeIO_OutputALtoIdeRegisterInDL
+	OUTPUT_AL_TO_IDE_REGISTER COMMAND_REGISTER_out
 
 	; Wait until command completed
 	pop		bx						; Pop status and timeout for polling
 	cmp		bl, FLG_STATUS_DRQ		; Data transfer started?
-	je		SHORT IdeTransfer_StartWithCommandInAL
+	je		SHORT IDEDEVICE%+Transfer_StartWithCommandInAL
 	test	BYTE [bp+IDEPACK.bDeviceControl], FLG_DEVCONTROL_nIEN
 	jz		SHORT .WaitForIrqOrRdy
-	jmp		IdeWait_PollStatusFlagInBLwithTimeoutInBH
+	jmp		IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
 
 ALIGN JUMP_ALIGN
 .WaitForIrqOrRdy:
-	jmp		IdeWait_IRQorStatusFlagInBLwithTimeoutInBH
+	jmp		IDEDEVICE%+Wait_IRQorStatusFlagInBLwithTimeoutInBH
 
 .DriveNotReady:
 	pop		bx							; Clean stack
-ReturnSinceTimeoutWhenPollingBusy:
+IDEDEVICE%+ReturnSinceTimeoutWhenPollingBusy:
 	ret
 
@@ -172,20 +167,19 @@
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
-IdeCommand_SelectDrive:
+IDEDEVICE%+Command_SelectDrive:
 	; Wait until neither Master or Slave Drive is busy
 	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_BSY, FLG_STATUS_BSY)
 	cmp		BYTE [bp+IDEPACK.bCommand], COMMAND_IDENTIFY_DEVICE
 	eCMOVE	bh, TIMEOUT_IDENTIFY_DEVICE
-	call	IdeWait_PollStatusFlagInBLwithTimeoutInBH
-	jc		SHORT ReturnSinceTimeoutWhenPollingBusy
+	call	IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
+	jc		SHORT IDEDEVICE%+ReturnSinceTimeoutWhenPollingBusy
 
 	; Select Master or Slave Drive
-	mov		dl, DRIVE_AND_HEAD_SELECT_REGISTER
 	mov		al, [bp+IDEPACK.bDrvAndHead]
-	call	IdeIO_OutputALtoIdeRegisterInDL
+	OUTPUT_AL_TO_IDE_REGISTER DRIVE_AND_HEAD_SELECT_REGISTER
 	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRDY, FLG_STATUS_DRDY)
 	cmp		BYTE [bp+IDEPACK.bCommand], COMMAND_IDENTIFY_DEVICE
 	eCMOVE	bh, TIMEOUT_IDENTIFY_DEVICE
-	jmp		IdeWait_PollStatusFlagInBLwithTimeoutInBH
+	jmp		IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
 
 
@@ -203,18 +197,16 @@
 ;		AL, BX, DX
 ;--------------------------------------------------------------------
+%ifdef ASSEMBLE_SHARED_IDE_DEVICE_FUNCTIONS
 ALIGN JUMP_ALIGN
 OutputSectorCountAndAddress:
-	mov		dl, SECTOR_COUNT_REGISTER
-	call	IdeIO_OutputALtoIdeRegisterInDL
+	OUTPUT_AL_TO_IDE_REGISTER SECTOR_COUNT_REGISTER
 
 	mov		al, ah
-	mov		dl, LBA_LOW_REGISTER
-	call	IdeIO_OutputALtoIdeRegisterInDL
+	OUTPUT_AL_TO_IDE_REGISTER LBA_LOW_REGISTER
 
 	mov		al, cl
-	mov		dl, LBA_MIDDLE_REGISTER
-	call	IdeIO_OutputALtoIdeRegisterInDL
+	OUTPUT_AL_TO_IDE_REGISTER LBA_MIDDLE_REGISTER
 
 	mov		al, ch
-	mov		dl, LBA_HIGH_REGISTER
-	jmp		IdeIO_OutputALtoIdeRegisterInDL
+	JUMP_TO_OUTPUT_AL_TO_IDE_REGISTER LBA_HIGH_REGISTER
+%endif
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeError.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeError.asm	(revision 234)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeError.asm	(revision 238)
@@ -18,8 +18,7 @@
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
-IdeError_GetBiosErrorCodeToAHfromPolledStatusRegisterInAL:
+IDEDEVICE%+Error_GetBiosErrorCodeToAHfromPolledStatusRegisterInAL:
 	mov		ah, al			; IDE Status Register to AH
-	mov		dl, ERROR_REGISTER_in
-	call	IdeIO_InputToALfromIdeRegisterInDL
+	INPUT_TO_AL_FROM_IDE_REGISTER ERROR_REGISTER_in
 	xchg	al, ah			; Status Register now in AL, Error Register now in AH
 
@@ -45,4 +44,5 @@
 ;		BX
 ;--------------------------------------------------------------------
+%ifdef ASSEMBLE_SHARED_IDE_DEVICE_FUNCTIONS
 ALIGN JUMP_ALIGN
 GetBiosErrorCodeToAHfromStatusAndErrorRegistersInAX:
@@ -92,2 +92,3 @@
 	db	RET_HD_BADSECTOR	; Bit7=BBK, Bad Block Detected
 	db	RET_HD_STATUSERR	; When Error Register is zero
+%endif
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeIrq.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeIrq.asm	(revision 234)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeIrq.asm	(revision 238)
@@ -111,6 +111,5 @@
 	mov		bl, FLGH_DPT_INTERRUPT_IN_SERVICE
 	call	FindDPT_ToDSDIforFlagsHighInBL
-	mov		dl, STATUS_REGISTER_in
-	call	IdeIO_InputToALfromIdeRegisterInDL
+	INPUT_TO_AL_FROM_IDE_REGISTER STATUS_REGISTER_in
 
 	; Clear Interrupt In-Service Flag from DPT
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm	(revision 234)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm	(revision 238)
@@ -97,10 +97,11 @@
 .WriteLastBlockToDrive:
 	mov		cx, [bp+PIOVARS.wWordsLeft]
+%ifdef USE_186
+	push	CheckErrorsAfterTransferringLastBlock
+	jmp		[bp+PIOVARS.fnXfer]					; Transfer possibly partial block
+%else
 	call	[bp+PIOVARS.fnXfer]					; Transfer possibly partial block
-
-	; Check for errors in last block
-	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRDY)
-	call	IdeWait_PollStatusFlagInBLwithTimeoutInBH
-	jmp		SHORT ReturnWithTransferErrorInAH
+	jmp		SHORT CheckErrorsAfterTransferringLastBlock
+%endif
 
 
@@ -155,4 +156,5 @@
 	; Check for errors in last block
 	mov		di, si								; DS:DI now points DPT
+CheckErrorsAfterTransferringLastBlock:
 	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRDY)
 	call	IdeWait_PollStatusFlagInBLwithTimeoutInBH
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeWait.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeWait.asm	(revision 234)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeWait.asm	(revision 238)
@@ -16,8 +16,10 @@
 ;		AL, BX, CX, DX
 ;--------------------------------------------------------------------
-IdeWait_IRQorDRQ:
+IDEDEVICE%+Wait_IRQorDRQ:
 	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRQ)
+%ifdef ASSEMBLE_SHARED_IDE_DEVICE_FUNCTIONS		; JR-IDE/ISA does not support IRQ
 	test	BYTE [bp+IDEPACK.bDeviceControl], FLG_DEVCONTROL_nIEN
-	jnz		SHORT IdeWait_PollStatusFlagInBLwithTimeoutInBH	; Interrupt disabled
+	jnz		SHORT IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH	; Interrupt disabled
+%endif
 	; Fall to IdeWait_IRQorStatusFlagInBLwithTimeoutInBH
 
@@ -35,6 +37,8 @@
 ;		AL, BX, CX, DX
 ;--------------------------------------------------------------------
-IdeWait_IRQorStatusFlagInBLwithTimeoutInBH:
+IDEDEVICE%+Wait_IRQorStatusFlagInBLwithTimeoutInBH:
+%ifdef ASSEMBLE_SHARED_IDE_DEVICE_FUNCTIONS		; JR-IDE/ISA does not support IRQ
 	call	IdeIrq_WaitForIRQ
+%endif
 	; Always fall to IdeWait_PollStatusFlagInBLwithTimeoutInBH for error processing
 
@@ -52,10 +56,10 @@
 ;		AL, BX, CX, DX
 ;--------------------------------------------------------------------
-IdeWait_PollStatusFlagInBLwithTimeoutInBH:
+IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH:
 	mov		ah, bl
 	mov		cl, bh
 	call	Timer_InitializeTimeoutWithTicksInCL
 	and		ah, ~FLG_STATUS_BSY
-	jz		SHORT PollBsyOnly
+	jz		SHORT IDEDEVICE%+PollBsyOnly
 	; Fall to PollBsyAndFlgInAH
 
@@ -72,17 +76,18 @@
 ;		AL, BX, CX, DX
 ;--------------------------------------------------------------------
+%ifdef ASSEMBLE_SHARED_IDE_DEVICE_FUNCTIONS
 PollBsyAndFlgInAH:
-	call	ReadIdeStatusRegisterToAL			; Discard contents for first read
+	call	IDEDEVICE%+ReadIdeStatusRegisterToAL; Discard contents for first read
 ALIGN JUMP_ALIGN
 .PollLoop:
-	call	ReadIdeStatusRegisterToAL
+	call	IDEDEVICE%+ReadIdeStatusRegisterToAL
 	test	al, FLG_STATUS_BSY					; Controller busy?
 	jnz		SHORT .UpdateTimeout				;  If so, jump to timeout update
 	test	al, ah								; Test secondary flag
-	jnz		SHORT IdeError_GetBiosErrorCodeToAHfromPolledStatusRegisterInAL
+	jnz		SHORT IDEDEVICE%+Error_GetBiosErrorCodeToAHfromPolledStatusRegisterInAL
 .UpdateTimeout:
 	call	Timer_SetCFifTimeout
 	jnc		SHORT .PollLoop						; Loop if time left
-	call	IdeError_GetBiosErrorCodeToAHfromPolledStatusRegisterInAL
+	call	IDEDEVICE%+Error_GetBiosErrorCodeToAHfromPolledStatusRegisterInAL
 	jc		SHORT .ReturnErrorCodeInAH
 	mov		ah, RET_HD_TIMEOUT					; Expected bit never got set
@@ -90,4 +95,5 @@
 .ReturnErrorCodeInAH:
 	ret
+%endif
 
 
@@ -103,14 +109,14 @@
 ;		AL, BX, CX, DX
 ;--------------------------------------------------------------------
-PollBsyOnly:
-	call	ReadIdeStatusRegisterToAL			; Discard contents for first read
+IDEDEVICE%+PollBsyOnly:
+	call	IDEDEVICE%+ReadIdeStatusRegisterToAL; Discard contents for first read
 ALIGN JUMP_ALIGN
 .PollLoop:
-	call	ReadIdeStatusRegisterToAL
+	call	IDEDEVICE%+ReadIdeStatusRegisterToAL
 	test	al, FLG_STATUS_BSY					; Controller busy?
-	jz		SHORT IdeError_GetBiosErrorCodeToAHfromPolledStatusRegisterInAL
+	jz		SHORT IDEDEVICE%+Error_GetBiosErrorCodeToAHfromPolledStatusRegisterInAL
 	call	Timer_SetCFifTimeout				; Update timeout counter
 	jnc		SHORT .PollLoop						; Loop if time left (sets CF on timeout)
-	jmp		SHORT IdeError_GetBiosErrorCodeToAHfromPolledStatusRegisterInAL
+	jmp		SHORT IDEDEVICE%+Error_GetBiosErrorCodeToAHfromPolledStatusRegisterInAL
 
 
@@ -125,5 +131,4 @@
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
-ReadIdeStatusRegisterToAL:
-	mov		dl, STATUS_REGISTER_in
-	jmp		IdeIO_InputToALfromIdeRegisterInDL
+IDEDEVICE%+ReadIdeStatusRegisterToAL:
+	JUMP_TO_INPUT_TO_AL_FROM_IDE_REGISTER STATUS_REGISTER_in
Index: trunk/XTIDE_Universal_BIOS/Src/Device/MemoryMappedIDE/MemIdeTransfer.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/MemoryMappedIDE/MemIdeTransfer.asm	(revision 238)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/MemoryMappedIDE/MemIdeTransfer.asm	(revision 238)
@@ -0,0 +1,239 @@
+; Project name	:	XTIDE Universal BIOS
+; Description	:	Memory mapped IDE Device transfer functions.
+
+; Structure containing variables for PIO transfer functions.
+; This struct must not be larger than IDEPACK without INTPACK.
+struc MEMPIOVARS
+	.wWordsInBlock			resb	2	; 0, Block size in WORDs
+	.wWordsLeft				resb	2	; 2, WORDs left to transfer
+	.wWordsDone				resb	2	; 4, Number of sectors xferred
+							resb	1	; 6, 
+							resb	1	; 7, IDEPACK.bDeviceControl
+	.fpDPT					resb	4	; 8, Far pointer to DPT
+endstruc
+
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; MemIdeTransfer_StartWithCommandInAL
+;	Parameters:
+;		AL:		IDE command that was used to start the transfer
+;				(all PIO read and write commands including Identify Device)
+;		ES:SI:	Ptr to normalized data buffer
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;		SS:BP:	Ptr to IDEPACK
+;	Returns:
+;		AH:		INT 13h Error Code
+;		CX:		Number of successfully transferred sectors
+;		CF:		Cleared if success, Set if error
+;	Corrupts registers:
+;		AL, BX, DX, SI, ES
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+MemIdeTransfer_StartWithCommandInAL:
+	; Initialize MEMPIOVARS
+	xchg	cx, ax								; IDE command to CL
+	xor		al, al
+	mov		ah, [bp+IDEPACK.bSectorCount]
+	mov		[bp+MEMPIOVARS.wWordsLeft], ax
+	cbw
+	mov		[bp+MEMPIOVARS.wWordsDone], ax		; Zero
+	mov		ah, [di+DPT_ATA.bSetBlock]
+	mov		[bp+MEMPIOVARS.wWordsInBlock], ax
+	mov		[bp+MEMPIOVARS.fpDPT], di
+	mov		[bp+MEMPIOVARS.fpDPT+2], ds
+
+	; Are we reading or writing?
+	test	cl, 16	; Bit 4 is cleared on all the read commands but set on 3 of the 4 write commands
+	jnz		SHORT .PrepareToWriteDataFromESSI
+	cmp		cl, COMMAND_WRITE_MULTIPLE
+	je		SHORT .PrepareToWriteDataFromESSI
+
+	; Prepare to read data to ES:DI
+	mov		di, si
+	push	cs
+	pop		ds
+	mov		si, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET
+	jmp		SHORT ReadFromSectorAccessWindowInDSSItoESDI
+
+ALIGN JUMP_ALIGN
+.PrepareToWriteDataFromESSI:
+	push	es
+	pop		ds
+	push	cs
+	pop		es
+	mov		di, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET
+	; Fall to WriteToSectorAccessWindowInESDIfromDSSI
+
+
+;--------------------------------------------------------------------
+; WriteToSectorAccessWindowInESDIfromDSSI
+;	Parameters:
+;		DS:SI:	Normalized ptr to buffer containing data
+;		ES:DI:	Ptr to Sector Access Window
+;		SS:BP:	Ptr to MEMPIOVARS
+;	Returns:
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;		AH:		BIOS Error code
+;		CX:		Number of successfully transferred sectors
+;		CF:		0 if transfer succesfull
+;				1 if any error
+;	Corrupts registers:
+;		AL, BX, DX, SI, ES
+;--------------------------------------------------------------------
+WriteToSectorAccessWindowInESDIfromDSSI:
+	; Always poll when writing first block (IRQs are generated for following blocks)
+	call	WaitUntilReadyToTransferNextBlock
+	jc		SHORT ReturnWithMemoryIOtransferErrorInAH
+
+ALIGN JUMP_ALIGN
+.WriteNextBlockToDrive:
+	mov		cx, [bp+PIOVARS.wWordsInBlock]
+	cmp		[bp+PIOVARS.wWordsLeft], cx
+	jbe		SHORT .WriteLastBlockToDrive
+	eMOVZX	dx, ch								; DX = Sectors in block
+	call	WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
+	call	WaitUntilReadyToTransferNextBlock
+	jc		SHORT ReturnWithMemoryIOtransferErrorInAH
+
+	; Increment number of successfully written WORDs
+	mov		ax, [bp+PIOVARS.wWordsInBlock]
+	sub		[bp+PIOVARS.wWordsLeft], ax
+	add		[bp+PIOVARS.wWordsDone], ax
+	jmp		SHORT .WriteNextBlockToDrive
+
+ALIGN JUMP_ALIGN
+.WriteLastBlockToDrive:
+	eMOVZX	dx, BYTE [bp+PIOVARS.wWordsLeft+1]	; Sectors left
+%ifdef USE_186
+	push	CheckErrorsAfterTransferringLastMemoryMappedBlock
+	jmp		WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
+%else
+	call	WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
+	jmp		SHORT CheckErrorsAfterTransferringLastMemoryMappedBlock
+%endif
+
+
+;--------------------------------------------------------------------
+; WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
+;	Parameters:
+;		DX:		Number of sectors in block
+;		DS:SI:	Normalized ptr to source buffer
+;		ES:DI:	Ptr to Sector Access Window
+;	Returns:
+;		CX, DX:	Zero
+;		SI:		Updated
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+WriteSingleBlockFromDSSIToSectorAccessWindowInESDI:
+	mov		cx, JRIDE_SECTOR_ACCESS_WINDOW_SIZE / 2
+	rep movsw
+	sub		di, JRIDE_SECTOR_ACCESS_WINDOW_SIZE	; Reset for next sector
+	dec		dx
+	jnz		SHORT WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
+	ret
+
+
+;--------------------------------------------------------------------
+; ReadFromSectorAccessWindowInDSSItoESDI
+;	Parameters:
+;		ES:DI:	Normalized ptr to buffer to recieve data
+;		DS:SI:	Ptr to Sector Access Window
+;		SS:BP:	Ptr to MEMPIOVARS
+;	Returns:
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;		AH:		BIOS Error code
+;		CX:		Number of successfully transferred sectors
+;		CF:		0 if transfer succesfull
+;				1 if any error
+;	Corrupts registers:
+;		AL, BX, DX, SI, ES
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+ReadFromSectorAccessWindowInDSSItoESDI:
+	call	WaitUntilReadyToTransferNextBlock
+	jc		SHORT ReturnWithMemoryIOtransferErrorInAH
+
+ALIGN JUMP_ALIGN
+.ReadNextBlockFromDrive:
+	mov		cx, [bp+PIOVARS.wWordsInBlock]
+	cmp		[bp+PIOVARS.wWordsLeft], cx
+	jbe		SHORT .ReadLastBlockFromDrive
+	eMOVZX	dx, ch								; DX = Sectors in block
+	call	ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
+	call	WaitUntilReadyToTransferNextBlock
+	jc		SHORT ReturnWithMemoryIOtransferErrorInAH
+
+	; Increment number of successfully read WORDs
+	mov		ax, [bp+PIOVARS.wWordsInBlock]
+	sub		[bp+PIOVARS.wWordsLeft], ax
+	add		[bp+PIOVARS.wWordsDone], ax
+	jmp		SHORT .ReadNextBlockFromDrive
+
+ALIGN JUMP_ALIGN
+.ReadLastBlockFromDrive:
+	eMOVZX	dx, BYTE [bp+PIOVARS.wWordsLeft+1]	; Sectors left
+	call	ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
+
+	; Check for errors in last block
+CheckErrorsAfterTransferringLastMemoryMappedBlock:
+	lds		di, [bp+MEMPIOVARS.fpDPT]			; DPT now in DS:DI
+	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRDY)
+	call	IDEDEVICE%+Wait_PollStatusFlagInBLwithTimeoutInBH
+
+	; Return number of successfully read sectors
+ReturnWithMemoryIOtransferErrorInAH:
+	lds		di, [bp+MEMPIOVARS.fpDPT]			; DPT now in DS:DI
+	mov		cx, [bp+PIOVARS.wWordsDone]
+	jc		SHORT .ConvertTransferredWordsInCXtoSectors
+	add		cx, [bp+PIOVARS.wWordsLeft]			; Never sets CF
+.ConvertTransferredWordsInCXtoSectors:
+	xchg	cl, ch
+	ret
+
+
+;--------------------------------------------------------------------
+; ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
+;	Parameters:
+;		DX:		Number of sectors in block
+;		ES:DI:	Normalized ptr to buffer to recieve data (destination)
+;		DS:SI:	Ptr to Sector Access Window (source)
+;	Returns:
+;		CX, DX:	Zero
+;		DI:		Updated
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+ReadSingleBlockFromSectorAccessWindowInDSSItoESDI:
+	mov		cx, JRIDE_SECTOR_ACCESS_WINDOW_SIZE / 2
+	rep movsw
+	sub		si, JRIDE_SECTOR_ACCESS_WINDOW_SIZE	; Reset for next sector
+	dec		dx
+	jnz		SHORT ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
+	ret
+
+
+;--------------------------------------------------------------------
+; WaitUntilReadyToTransferNextBlock
+;	Parameters:
+;		SS:BP:	Ptr to MEMPIOVARS
+;	Returns:
+;		AH:		INT 13h Error Code
+;		CF:		Cleared if success, Set if error
+;	Corrupts registers:
+;		AL, BX, CX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+WaitUntilReadyToTransferNextBlock:
+	push	ds
+	push	di
+	lds		di, [bp+MEMPIOVARS.fpDPT]			; DPT now in DS:DI
+	call	IDEDEVICE%+Wait_IRQorDRQ			; Always polls
+	pop		di
+	pop		ds
+	ret
Index: trunk/XTIDE_Universal_BIOS/Src/Device/MemoryMappedIDE/MemMappedIDE.inc
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/MemoryMappedIDE/MemMappedIDE.inc	(revision 238)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/MemoryMappedIDE/MemMappedIDE.inc	(revision 238)
@@ -0,0 +1,68 @@
+; Project name	:	XTIDE Universal BIOS
+; Description	:	Macros for memory mapped ATA controllers.
+
+%ifndef MEM_MAPPED_IDE_INC
+%define MEM_MAPPED_IDE_INC
+
+JRIDE_SECTOR_ACCESS_WINDOW_OFFSET			EQU	3C00h	; 512 byte IDE Sector Access Window
+JRIDE_COMMAND_BLOCK_REGISTER_WINDOW_OFFSET	EQU	3E00h	; 8 byte CS0 IDE Register Window
+JRIDE_CONTROL_BLOCK_REGISTER_WINDOW_OFFSET	EQU	3E08h	; 8 byte CS1 IDE Register Window
+JRIDE_SECTOR_ACCESS_WINDOW_SIZE				EQU	512		; 512 bytes
+
+
+
+;--------------------------------------------------------------------
+; OUTPUT_AL_TO_IDE_REGISTER_IN_DL
+; JUMP_TO_OUTPUT_AL_TO_IDE_REGISTER_IN_DL
+; OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER_IN_DL
+;	Parameters:
+;		AL:		Byte to output
+;		%1:		IDE Register				(OUTPUT_AL_TO_IDE_REGISTER)
+;				IDE Control Block Register	(OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER)
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		BX, DX
+;--------------------------------------------------------------------
+%unmacro OUTPUT_AL_TO_IDE_REGISTER 1
+%macro OUTPUT_AL_TO_IDE_REGISTER 1
+	mov		[cs:JRIDE_COMMAND_BLOCK_REGISTER_WINDOW_OFFSET+%1], al
+%endmacro
+
+%unmacro JUMP_TO_OUTPUT_AL_TO_IDE_REGISTER 1
+%macro JUMP_TO_OUTPUT_AL_TO_IDE_REGISTER 1
+	OUTPUT_AL_TO_IDE_REGISTER %1
+	ret
+%endmacro
+
+%unmacro OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER 1
+%macro OUTPUT_AL_TO_IDE_CONTROL_BLOCK_REGISTER 1
+	mov		[cs:JRIDE_CONTROL_BLOCK_REGISTER_WINDOW_OFFSET+%1], al
+%endmacro
+
+
+;--------------------------------------------------------------------
+; INPUT_TO_AL_FROM_IDE_REGISTER
+; JUMP_TO_INPUT_TO_AL_FROM_IDE_REGISTER
+;	Parameters:
+;		%1:		IDE Register
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;	Returns:
+;		AL:		Inputted byte
+;	Corrupts registers:
+;		BX, DX
+;--------------------------------------------------------------------
+%unmacro INPUT_TO_AL_FROM_IDE_REGISTER 1
+%macro INPUT_TO_AL_FROM_IDE_REGISTER 1
+	mov		al, [cs:JRIDE_COMMAND_BLOCK_REGISTER_WINDOW_OFFSET+%1]
+%endmacro
+
+%unmacro JUMP_TO_INPUT_TO_AL_FROM_IDE_REGISTER 1
+%macro JUMP_TO_INPUT_TO_AL_FROM_IDE_REGISTER 1
+	INPUT_TO_AL_FROM_IDE_REGISTER %1
+	ret
+%endmacro
+
+
+%endif ; MEM_MAPPED_IDE_INC
