⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbmbb.asm

📁 dos下的USB源码(包括UHCI
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	jne	UMCBT_DataTransferError

	sub	cx, bx				; decrement count
	or	cx, cx
	jnz	UMCBT_NextDataTransport

; Successfull completion. Clear Zero flag
	or	sp, sp
	jmp	SHORT UMCBT_Exit

UMCBT_DataTransferError:

; Error! Set zero flag
	cmp	sp, sp

UMCBT_Exit:
	pop	di
	pop	ecx
	pop	bx
	pop	eax
	ret
USBM_ConsumeBulkData	ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	USBM_ProcessBulkData
;
; Description:	This function reads/writes the data to the mass storage
;		device using bulk transfer. It also takes care of pre and
;		post skip bytes.
;
; Input: 	stMassXactStruc
;		  bXferDir	Transfer direction
;		  fpBuffer	Data buffer far pointer
;		  dwLength	Amount of data to be transferred
;		  wPreSkip	Number of bytes to skip before data
;		  wPostSkip	Number of bytes to skip after data
;
; Output: 	ZR	On error
;		NZ	On successful completion
;			EAX	Amount of data actually transferred
;
; Modified:	EAX
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

USBM_ProcessBulkData	PROC NEAR SYSCALL PUBLIC

	push	cx
	push	dx
	push	di

; Find the actual size to be read
; Actual size to be read = (Total size  - (pre + post skip))
	movzx	eax, stMassXactStruc.wPreSkip
	sub	stMassXactStruc.dwLength, eax
	movzx	eax, stMassXactStruc.wPostSkip
	sub	stMassXactStruc.dwLength, eax

	xor	eax, eax		; Return value
; Check whether something we have to transfer
	cmp	stMassXactStruc.dwLength, 0
	je	UMPBD_Success

; Set the direction
	mov	dl, stMassXactStruc.bXferDir

; Check whether pre skip is needed
	cmp	stMassXactStruc.wPreSkip, 0
	je	UMPBD_NoPreSkipBytes

; Consume the unwanted pre-skip data
	mov	cx, stMassXactStruc.wPreSkip
	call	USBM_ConsumeBulkData		; Preserves EAX
	jz	UMPBD_Exit		; Error ? Exit !

UMPBD_NoPreSkipBytes:

	push	es
	les	di, stMassXactStruc.fpBuffer
	mov	ecx, stMassXactStruc.dwLength
	call	USBM_IssueBulkTransfer
	pop	es
	jz	UMPBD_Exit

; EAX actual data size

; Check whether post skip is needed
	cmp	stMassXactStruc.wPostSkip, 0
	je	UMPBD_Success

	mov	cx, stMassXactStruc.wPostSkip
	call	USBM_ConsumeBulkData		; Preserves EAX
; Since we already read the requested number of bytes it does not matter
; whether the post skip read is successful or not

UMPBD_Success:
	or	sp, sp

UMPBD_Exit:
	pop	di
	pop	dx
	pop	cx
	ret
USBM_ProcessBulkData	ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	USBM_ClearBulkEndpointStall
;
; Description:	This function clears the bulk endpoint stall by sending
;		CLEAR_FEATURE command to bulk endpoints
;
; Input: 	AL	Endpoint direction
;			= 0FFh	Clear both bulk IN & OUT
;			BIT7 = 0	Only Bulk OUT
;			BIT7 = 1	Only Bulk IN
;
; Output: 	Nothing
;
; Modified:	None
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

USBM_ClearBulkEndpointStall	PROC NEAR SYSCALL PUBLIC

	push	ax
	push	cx
	push	dx
	push	si

	xor	cx, cx
	xor	dx, dx

; Set SI to the current devices device info structure
	mov	si, OFFSET CurrentDevice
	mov	CurrentDevice.CntrlXfer.wValue, ENDPOINT_HALT
	mov	CurrentDevice.CntrlXfer.wRequest, ENDPOINT_CLEAR_PORT_FEATURE

	cmp	al, 0FFH
	je	UMCBES_Continue

; Save AL in DL
	mov	dl, al
	dec	dh		; DH = 0FFh

UMCBES_Continue:
	mov	cl, CurrentDevice.bBulkInEndpoint
	or	cl, BIT7
	test	dl, BIT7
	jnz	UMCBES_EndpointFound

; Bulk OUT endpoint
	mov	cl, CurrentDevice.bBulkoutEndpoint
UMCBES_EndpointFound:

; Issue clear port feature command 
	mov	CurrentDevice.CntrlXfer.wIndex, cx
	call	USBBB_IssueControlXferWithoutData

; Reset the toggle bit
	mov	cl, USB_BULK_IN_DATA_SYNC_SHIFT
	test	dl, BIT7
	jnz	UMCBES_InPacket
; It is an OUT transaction get appropriate size
	mov	cl, USB_BULK_OUT_DATA_SYNC_SHIFT
UMCBES_InPacket:
; Reset toggle bit
	mov	al, 1
	shl	al, cl
	not	al
	and	CurrentDevice.bDataSync, al

; Check whether the request is for both endpoints
	or	dh, dh
	jnz	UMCBES_Exit

; Set DL for next endpoint (IN)
	or	dl, BIT7
	dec	dh		; Set end condition
	jmp	SHORT UMCBES_Continue

UMCBES_Exit:
	pop	si
	pop	dx
	pop	cx
	pop	ax
	ret
USBM_ClearBulkEndpointStall	ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	USBM_ClearMassBuffers
;
; Description:	This function clears the mass transaction structure & mass
;		command buffer
;
; Input: 	Nothing
;
; Output: 	DI	Pointer to the mass command buffer
;
; Modified:	DI
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

USBM_ClearMassBuffers	PROC NEAR SYSCALL
	pushf
	push	ax
	push	cx
	push	es

	cld
	push	ds
	pop	es
	mov	di, OFFSET stMassXactStruc
	xor	ax, ax
	mov	cx, SIZE MASS_XACT_STRUC
	rep	stosb

	mov	di, OFFSET aMassCommandBuffer
	push	di
	mov	cx, USB_MASS_COMMAND_BUFFER_SIZE
	rep	stosb
	pop	di
	mov	stMassXactStruc.pCmdBuffer, di

	pop	es
	pop	cx
	pop	ax
	popf
	ret
USBM_ClearMassBuffers	ENDP


;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	USBINT13Handler
;
; Description:	This function is the INT13h interface handler for the USB
;		mass storage device
;
; Input: 	AH	Function number
;		DL	Drive number
;		DH	Head number
;		CH	Low byte of the cylinder number
;		CL[5-0]	Start sector number
;		CL[7-6]	Bit 8 & 9 of the cylinder number
;		AL	Sector count
;
; Output:	AH	Operation status - return value
;		CY	On error
;		NC	On success
;		CX, DX	Return value for functions 8 & 15
;
; Modified:	Only the registers which needs to return value are modified
;		rest restored
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

USBINT13Handler			PROC NEAR PUBLIC
	cli
; Do not add/remove any push or pop at this point. If changes has to be done
; verify with the equates defined above.
	push    es
	push    ds
	pushad
	mov     bp, sp

; Set DS & ES value
	mov	ax, USB_DSEG
	mov	ds, ax
	mov	es, ax

; Load the INT13h function number (was AH) to DI
	mov	al, BYTE PTR (USBI13RegAccess PTR [bp+1]).dRegEAX

; Check for HDD call
	test	dl, 80h
	jnz	UI13_InvalidFunction

; Floppy INT-13H Path
; Check for function number validity
	cmp	al, 2		; Check for read
	jne	UI13_InvalidFunction

; Invoke the read call
	call	USBM_ReadFromUSBDevice
	jmp	SHORT UI13H_SetReturnCode

UI13_InvalidFunction:
	mov	ah, 1

UI13H_SetReturnCode:
	mov	BYTE PTR (USBI13RegAccess PTR [bp+1]).dRegEAX, ah	; return code

	cmp     ah, 1
	cmc                             ; NC/CY for ok/error
UI13H_Exit:
	popad
	pop     ds
	pop     es
	sti
	retf    2

USBINT13Handler			ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	USBM_ReadFromUSBDevice
;
; Description:	This function is the common read/write/verify function
;
; Input: 	BP	Pointer to stack frame where all the register values 
;			are saved:
;			AL	Number of sectors to read
;			CH	Low 8bits of 10bit cylinder number (0 based)
;			CL	Bit 7-6 : High 2 bits of 10bit cylinder num
;			CL	Bit 5-0 : Starting sector number (1 based)
;			DH	Head number (0 based)
;			ES:BX	Pointer to the read buffer
;		CX	Routine used to prepare URP structure
;
; Output: 	AH	0 on success
;			<> 0 on error
;
; Modified:	All general purpose registers (except SP & BP)
;
; Referrals:	USBLocalStore, URP_STRUC
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

dTempStartLBA		DWORD		?

USBM_ReadFromUSBDevice		PROC NEAR PUBLIC

; Convert the CHS to LBA
; Find the start sector number and cylinder number
	mov	al, BYTE PTR (USBI13RegAccess PTR [bp]).dRegECX
	and	al, 3Fh			; AX - Start sector number
	mov	cl, al

; Get Cylinder number
	mov	ax, WORD PTR (USBI13RegAccess PTR [bp]).dRegECX
	shr	al, 06h
	xchg	al, ah				; AX - Cylinder number
	mov	bx, ax

	mov	al, stMassDeviceInfo.bSectors	; Sectors/track
	mul	stMassDeviceInfo.bHeads		; Num. Heads

; AX - Number of heads * sectors per track
	mul	bx
; DX:AX - Start sector of cylinder
	push	dx
	push	ax
	pop	ebx			; EBX = start sector of cylinder
	movzx	eax, cl			; 1 based
	dec	eax			; 0 based
	add	ebx, eax

; Get head number * number of sectors / track
	mov	al, stMassDeviceInfo.bSectors	; Sectors/track
	mul	BYTE PTR (USBI13RegAccess PTR [bp+1]).dRegEDX ; Head number
	movzx	eax, ax
	add	eax, ebx				; Start LBA

; Check for forced floppy emulated device and change LBA accordingly
	cmp	stMassDeviceInfo.bEmuType, \
					USB_EMU_FORCED_FDD
	jne	UIFU_NotForcedFDD

; Skip first track in case of floppy emulation
	movzx	ebx, stMassDeviceInfo.bHiddenSectors
	add	eax, ebx

; Save the LBA
	mov	CS:dTempStartLBA, eax

UIFU_NotForcedFDD:


	push	eax
	movzx	cx, BYTE PTR (USBI13RegAccess PTR [bp]).dRegEAX
; CX - Block count
	push	cx

; Load sector size in CX (in bytes)
	mov	cx, stMassDeviceInfo.wBlockSize
; CX		Sector size in bytes
	movzx	eax, WORD PTR (USBI13RegAccess PTR [bp]).dRegEBX
	mov	bx, ax
	shr	ax, 4
	add	ax, (USBI13RegAccess PTR [bp]).wRegES
	shl	eax, 16
; Modify BX to make only lowest nibble significant
	and	bx, 000Fh
	mov	ax, bx
	mov	edi, eax		; EDI - Normalized address

	xor	ax, ax
	mov	dx, 1
	sub	ax, bx			; Max # of bytes that can be xferred
	sbb	dx, 0
	div	cx			; Divide by sector size
	mov	cx, bx			; ES:CX = normalized address
	mov	dl, al			; Max # of sectors that can be xferred

	pop	cx		; Number of blocks to read
	pop	eax		; Start LBA
	cmp	dl, BYTE PTR (USBI13RegAccess PTR [bp]).dRegEAX
					; if requested count is more than the limit
	jb	UIFU_TooMuch		; Exit

	xor	ebx, ebx		; Pre/post skip bytes = 0
	call	USBM_ReadDevice
	jnz	UIFU_Success
	mov	ah, 80h		; Timeout error
	jmp	SHORT UIFU_exit

UIFU_TooMuch:
	mov	ah, 09h			; Data extends too long error
	jmp	SHORT UIFU_Exit

UIFU_Success:

	xor	ah, ah
; Check for forced floppy emulated device
	cmp	stMassDeviceInfo.bEmuType, \
					USB_EMU_FORCED_FDD
	jne	UIFU_Exit

; Check whether we read first LBA
	cmp	CS:dTempStartLBA, 0
	jne	UIFU_Exit

	push	es
	push	bx
; This is a floppy emulated ZIP drive, with read to first sector. Update
; the boot record so that floppy emulation is okay.
	push	edi
	pop	bx
	pop	es
	mov	DWORD PTR ES:[bx+0Bh+11h], 0000h	; Force #of hidden sectors to 0
; For FAT32, physical drive number is present in offset 40h
	mov	ax, 24h		; Offset for FAT16/FAT
;;	cmp	DWORD PTR ES:[bx+52h], '3TAF'	; FAT3..
;;	jne	UPRCC_NotFAT32
;;	mov	ax, 40h
;;UPRCC_NotFAT32:
	add	bx, ax
	mov	BYTE PTR ES:[bx], 00h		; Force physical drive# to 0

	pop	bx
	pop	es

UIFU_Exit:
	ret
USBM_ReadFromUSBDevice		ENDP

	PUBLIC	_USBMBB_ASM_END
_USBMBB_ASM_END		LABEL		BYTE
;----------------------------------------------------------------------------
;			END OF ROUTINES
;----------------------------------------------------------------------------
USB_CSEG	ENDS
	END

;***************************************************************************;
;***************************************************************************;
;**                                                                       **;
;**           (C)Copyright 1985-2002, American Megatrends, Inc.           **;
;**                                                                       **;
;**                          All Rights Reserved.                         **;
;**                                                                       **;
;**                6145-F Northbelt Pkwy, Norcross, GA 30071              **;
;**                                                                       **;
;**                          Phone (770)-246-8600                         **;
;**                                                                       **;
;***************************************************************************;
;***************************************************************************;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -