.386
LOCALS

.MODEL	FLAT


;*******************************************************************************
;Блок информации, передаваемый по команде идентификации устройства EC
;*******************************************************************************
IDEDEVINFOSTRUC	STRUC
	idi_wGenConfig		DW	?	;бит 6  - фикс-ное устройство
						;бит 7  - съемное устройство
						;бит 15 - устройство ATAPI/IDE:
						;   1 - устройство ATAPI
						;   0 - устройство IDE
	idi_wCyls		DW	?
	idi_wReserved1		DW	?
	idi_wHeads		DW	?
	idi_wBytesPerTrack	DW	?
	idi_wBytesPerSector	DW	?
	idi_wSecsPerTrack	DW	?
	idi_wVendorSpec1	DW	3 DUP(?)
	idi_sSerialNumber	DB	20 DUP(?)
	idi_wBufferType		DW	?
	idi_wBufferSize		DW	?
	idi_wECCBytes		DW	?
	idi_sFirmwareRev	DB	8 DUP(?)
	idi_sModelNumber	DB	40 DUP(?)
	idi_wVendorSpec2	DW	?
	idi_wDoubleWordIO	DW	?
	idi_wCapabilities	DW	?
	idi_wReserved2		DW	?
	idi_wPIOTimingMode	DW	?
	idi_wDMATimingMode	DW	?
	idi_wExtValid		DW	?
	idi_wCurrCyls		DW	?
	idi_wCurrHeads		DW	?
	idi_wCurrSecsPerTrack	DW	?
	idi_dwCurrCapacity	DD	?
	idi_wMultSectorStuff	DW	?
	idi_dwTotalAddrSecs	DD	?
	idi_wSingleWordDMA	DW	?
	idi_wMultiwordDMA	DW	?
	idi_wAdvancedPIO	DW	?
	idi_wMinDMACycle	DW	?
	idi_wRecDMACycle	DW	?
	idi_wMinPIOCycle	DW	?
	idi_wMinPIOCyclewIORDY	DW	?
	idi_wReserved3		DW	11 DUP(?)
	idi_wMajorVerNum	DW	?
	idi_wMinorVerNum	DW	?
	idi_wCommandSet1	DW	?
	idi_wCommandSet2	DW	?
	idi_wReserved4		DW	44 DUP(?)
	idi_wSecurityStatus	DW	?
	idi_wVendorSpec3	DW	31 DUP(?)
	idi_wReserved5		DW	96 DUP(?)
IDEDEVINFOSTRUC	ENDS

;*******************************************************************************
;Блок информации, передаваемый по ATA-команде A1
;*******************************************************************************
ATAPIDEVINFOSTRUC	STRUC
	adi_wGenConfig		DW	?	;биты 0-1  - длина пакета:
						;  00 - 12 байт
						;  01 - 16 байт
						;  10 - зарезервировано
						;  11 - зарезервировано
						;биты 2-4  - ?
						;биты 5-6  - CMD DRQ Type:
						;  00 - Микропроцессор
						;  01 - Interrupt
						;  10 - Accelerated
						;  11 - зарезервировано
						;бит 7     - съемное устройство
						;биты 8-12 - тип устройства:
						;  05 - CD-ROM
						;бит 15    - устройство ATAPI/IDE:
						;   1 - устройство ATAPI
						;   0 - устройство IDE
	adi_wReserved1		DW	9 DUP(?)
	adi_sSerialNumber	DB	20 DUP(?)
	adi_wVendorSpec1	DW	3 DUP(?)
	adi_sFirmwareRev	DB	8 DUP(?)
	adi_sModelNumber	DB	40 DUP(?)
	adi_wVendorSpec2	DW	209 DUP(?)
ATAPIDEVINFOSTRUC	ENDS


.CODE

PUBLIC	GetATAPIDevInfo
PUBLIC	GetIDEDevInfo
PUBLIC	DetectATAPIDev
PUBLIC	CorrectDevInfo

;*******************************************************************************
;GetATAPIDevInfo получает информацию об устройстве ATAPI
;*******************************************************************************
;Использует:	DevWait, CorrectDevInfo
;
;Вызов:		DX = базовый порт
;		AL = номер устройства
;		EDI -> буфер для информации об устройстве
;
;Возврат:	CF = флаг успешного/неудачного завершения
;
;Изменяемые
;  регистры:	AX,ECX,DX,Flags
;*******************************************************************************
GetATAPIDevInfo	PROC

		mov	ah,0A1h		;AH=0A1h (команда идентификации
					;устройства ATAPI)
		jmp	GetDeviceInfo

;*******************************************************************************
;GetIDEDevInfo	получает информацию об устройстве IDE
;*******************************************************************************
;Использует:	DevWait, CorrectDevInfo
;
;Вызов:		DX = базовый порт
;		AL = номер устройства
;		EDI -> буфер для информации об устройстве
;
;Возврат:	CF = флаг успешного/неудачного завершения
;
;Изменяемые
;  регистры:	AX,ECX,DX,Flags
;*******************************************************************************
GetIDEDevInfo:
		mov	ah,0ECh		;AH=0ECh (команда идентификации
					;устройства IDE)

GetDeviceInfo:
		and	al,1
		shl	al,4
		or	al,0A0h
		add	dx,6		;DX = регистр выбора устройства/головки
		out	dx,al		;выбор устройства

		inc	dx		;DX = регистр команды/состояния
		in	al,dx		;AL = байт состояния устройства
		cmp	al,0FFh
		je	@@Error

		call	DevWait
		jc	@@Error

		mov	al,ah
		out	dx,al		;команда получения информации
					;об устройстве

		call	DevWait
		jc	@@Error

		mov	ecx,100h
@@WaitLoop:	in	al,dx		;AL = байт состояния устройства
		test	al,8		;установлен бит DRQ?
		jnz	@@Ok
		loop	@@WaitLoop

@@Error:	stc

		ret

@@Ok:		sub	dx,7		;DX = регистр данных

		push	edi

		mov	ecx,100h
		cld
		cli
		rep	insw		;чтение данных
		sti

		pop	edi

		add	dx,7		;DX = регистр команды/состояния
		in	al,dx		;AL = байт состояния устройства
		and	al,71h
		cmp	al,50h
		jne	@@Error

		call	CorrectDevInfo	;коррекция информации

		clc

		ret

GetATAPIDevInfo	ENDP

;*******************************************************************************
;DetectATAPIDev	определяет наличие устройства ATAPI
;*******************************************************************************
;Использует:	DevWait
;
;Вызов:		DX = базовый порт
;		AL = номер устройства
;
;Возврат:	CF = флаг успешного/неудачного завершения
;
;Изменяемые
;  регистры:	AX,ECX,DX,Flags
;*******************************************************************************
DetectATAPIDev	PROC

		and	al,1
		shl	al,4
		or	al,0A0h
		add	dx,6		;DX = регистр выбора устройства/головки
		out	dx,al		;выбор устройства

		inc	dx		;DX = регистр команды/состояния
		in	al,dx		;AL = байт состояния устройства
		cmp	al,0FFh
		je	@@NoDevice

		call	DevWait
		jc	@@NoDevice

;		mov	al,8		;AL=8 (команда общего сброса)
;		out	dx,al
;
;		call	DevWait
;		jc	@@NoDevice

		sub	dx,3		;DX = регистр цилиндра (младший байт)
		xor	al,al
		out	dx,al
		inc	dx		;DX = регистр цилиндра (старший байт)
		out	dx,al

		inc	dx
		inc	dx		;DX = регистр команды/состояния
		mov	al,0ECh		;AL=0ECh (команда идентификации устройства)
		out	dx,al

		call	DevWait
		jc	@@NoDevice

		sub	dx,3		;DX = регистр цилиндра (младший байт)
		in	al,dx
		mov	ah,al
		inc	dx		;DX = регистр цилиндра (старший байт)
		in	al,dx
		cmp	ax,14EBh
		je	@@Exit

@@NoDevice:	stc

@@Exit:		ret

DetectATAPIDev	ENDP

;*******************************************************************************
;DevWait	ожидает, пока устройство занято
;*******************************************************************************
;Использует:	нет
;
;Вызов:		DX = регистр команды/состояния
;
;Возврат:	CF = флаг успешного/неудачного завершения
;
;Изменяемые
;  регистры:	AL,ECX,Flags
;*******************************************************************************
DevWait		PROC

		mov	ecx,140000h
@@WaitLoop:	in	al,dx		;AL = байт состояния устройства
		test	al,80h		;устройство занято?
		jz	@@Exit
		loop	@@WaitLoop

		stc

@@Exit:		ret

DevWait		ENDP

;*******************************************************************************
;CorrectDevInfo	корректирует информацию об устройстве IDE/ATAPI
;*******************************************************************************
;Использует:	нет
;
;Вызов:		EDI -> буфер с информацией об устройстве
;
;Возврат:	нет
;
;Изменяемые
;  регистры:	AX,ECX,Flags
;*******************************************************************************
CorrectDevInfo	PROC

		push	edi

		add	edi,14h
		mov	ecx,0Ah
@@SerNumLoop:	mov	ax,[edi]
		xchg	al,ah
		stosw
		loop	@@SerNumLoop

		add	edi,6
		mov	cl,18h
@@ModelNumLoop:	mov	ax,[edi]
		xchg	al,ah
		stosw
		loop	@@ModelNumLoop

		pop	edi

		ret

CorrectDevInfo	ENDP


END
