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

📄 usbmbb.asm

📁 dos下的USB源码(包括UHCI
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	call	USBM_IssueMassTransaction
UMRD_Exit:
	pop	edx
	pop	si
	pop	eax
	ret
USBM_ReadDevice		ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	USBM_UpdateCHSFromBootRecord
;
; Description:	This function parses the boot record and extract the CHS 
;		information of the formatted media from the boot record. 
;		This routine checks for DOS & NTFS formats only
;
; Input: 	DS:DI	Boot record of the device
;
; Output: 	ZR	If the boot record is un-recognizable and CHS info
;			is not extracted
;		NZ	If the boot record is recognizable and CHS info
;			is extracted. CHS information is updated in the
;			mass device info structure
;
; Modified:	None
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

USBM_UpdateCHSFromBootRecord	PROC NEAR SYSCALL

	push	eax
	push	ecx
	push	dx

; Check for valid MSDOS/MSWIN/NTFS boot record
	mov	eax, DWORD PTR [di+3]
	cmp	eax, 'ODSM'			; MSDO..
	je	UMGFT_GetCHSFromBootRecord
	cmp	eax, 'IWSM'			; MSWI..
	je	UMGFT_GetCHSFromBootRecord

; Check for valid FAT,FAT16 boot records
	mov	BYTE PTR [di+39h], 20h
	cmp	DWORD PTR [di+36h], ' TAF'			; FAT
	je	UMGFT_GetCHSFromBootRecord
;;; It may be FAT32, check that too
;;	cmp	DWORD PTR [di+52h], '3TAF'			; FAT3
;;	je	UMGFT_GetCHSFromBootRecord

; Invalid boot record. Return with error.
	cmp	sp, sp
	jmp	SHORT UMUCFBR_Exit

UMGFT_GetCHSFromBootRecord:

; Check what information we got from the device.
; If the device supports ReadCapacity command then we have only the last LBA
; value and the block size. So calculate cylinder value from the last LBA &
; head & sector value found in the boot record
; If the device supports ModeSense command then we have CHS information and
; block size value but not the last LBA value. So calculate last LBA from the
; CHS information

	test	wUSBCommandStatus, USB_CMDSTS_READ_CAPACITY_DONE
	jz	UMGFT_CheckForModeSense
; Calculate cylinder value
	xor	ax, ax
	mov	al, BYTE PTR [di+18h]		; Sectors/track
	mov	stMassDeviceInfo.bSectors, al
	mov	al, BYTE PTR [di+1Ah]		; heads
	mov	stMassDeviceInfo.bHeads, al

	mul	stMassDeviceInfo.bSectors
	mov	ecx, stMassDeviceInfo.dMaxLBA
	xchg	eax, ecx
	push	eax
	pop	ax
	pop	dx
	div	cx
	mov	stMassDeviceInfo.wCylinders, ax
	jmp	SHORT UMUCFBR_Done

UMGFT_CheckForModeSense:
	test	wUSBCommandStatus, USB_CMDSTS_MODE_SENSE_DONE
	jz	UMUCFBR_Done
; Calculate last LBA value
	xor	ax, ax
	mov	al, stMassDeviceInfo.bSectors
	mul	stMassDeviceInfo.bHeads
	xor	dx, dx
	mul	stMassDeviceInfo.wCylinders
	push	dx
	push	ax
	pop	eax
	dec	eax
	mov	stMassDeviceInfo.dMaxLBA, eax

UMUCFBR_Done:
	or	sp, sp
UMUCFBR_Exit:
	pop	dx
	pop	ecx
	pop	eax
	ret
USBM_UpdateCHSFromBootRecord	ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	USBM_GetFormatType
;
; Description:	This function reads the first sector from the mass storage
;		device and identifies the formatted type.
;
; Input: 	None
;
; Output: 	ZR	If could not identify the formatted type
;		NZ	If formatted type is identified
;
; Modified:	Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

USBM_GetFormatType		PROC NEAR PUBLIC

	push	eax
	push	ebx
	push	cx
	push	dx
	push	edi

; Read the first sector of the device
; Set the LBA number to 0
	xor	eax, eax
	push	ds
	push	OFFSET ControlDataBuffer
	pop	edi
	mov	cx, 1			; Number of blocks
	xor	ebx, ebx		; Pre/post skip bytes
	call	USBM_ReadDevice
	jz	UMGFT_Exit

; Check for validity of the partition table/boot record
	cmp	WORD PTR [di+1FEh], 0AA55h
	jne	UMGFT_SkipNotSuccess

; Check whether it has valid partition table

	add	di, 1BEh		; Start offset of partition table
	xor	ax, ax
	mov	dx, ax
; DX	Contains first valid partition table entry

	mov	ecx, stMassDeviceInfo.dMaxLBA

UMGFT_VerifyPartitionTable:
	cmp	DWORD PTR [di+8], 0
	jz	UMGFT_CheckNextEntry

	cmp	DWORD PTR [di+8], ecx
	ja	UMGFT_InvalidPartitionTable	; FDD

	inc	ah
	or	dx, dx
	jnz	UMGFT_CheckNextEntry
	mov	dx, di
UMGFT_CheckNextEntry:
	add	di, 10h			; Point to next partition table entry
	inc	al
	cmp	al, 4
	jb	UMGFT_VerifyPartitionTable

; Check for valid partition table
	cmp	ah, 1
	jb	UMGFT_InvalidPartitionTable

; Valid partition table found. Check number of entries in the partition table
	mov	ax, dx		; Offset to the valid partition table entry

; Assume emulation as Forced FDD.
	mov	dx, (USB_EMU_FORCED_FDD SHL 8) + USB_MASS_DEV_ARMD

; Read boot sector
; Set the LBA number to boot record LBA number
	mov	di, OFFSET ControlDataBuffer
	push	di
	mov	di, ax
	mov	eax, DWORD PTR [di+8]
	pop	di
; Save hidden sector value
	mov	stMassDeviceInfo.bHiddenSectors, al
	push	ds
	push	di
	pop	edi
	mov	cx, 1			; Number of blocks
	xor	ebx, ebx		; Pre/post skip bytes
	call	USBM_ReadDevice
	jz	UMGFT_Exit

UMGFT_VerifyBootRecord:
	mov	di, OFFSET ControlDataBuffer
; DS:DI	Boot record
	call	USBM_UpdateCHSFromBootRecord
	jz	UMGFT_Exit		; Unrecognizable media
	jmp	SHORT UMGFT_EmulationFound

UMGFT_InvalidPartitionTable:
; Assume the emulation as floppy
	mov	dx, (USB_EMU_FLOPPY_ONLY SHL 8) + USB_MASS_DEV_ARMD
	jmp	SHORT UMGFT_VerifyBootRecord

UMGFT_EmulationFound:
; Set the emulation type
	mov	stMassDeviceInfo.bDevType, dl
	mov	stMassDeviceInfo.bEmuType, dh
; Clear the carry flag indicating success
	or	sp, sp		; 
	jmp	SHORT UMGFT_Exit

UMGFT_SkipNotSuccess:
; Set zero flag
	cmp	sp, sp
UMGFT_Exit:
	pop	edi
	pop	dx
	pop	cx
	pop	ebx
	pop	eax
	ret
USBM_GetFormatType		ENDP


Comment ~

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	USBM_InquiryCommand
;
; Description:	This function sends inquiry command to the USB mass storage
;		device
;
; Input: 	None
;
; Output: 	ZR	On error
;		NZ	On successfull completion
;			bDevType	Device type information
;
; Modified:	None
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

USBM_InquiryCommand 	PROC	NEAR SYSCALL PUBLIC

	push	eax
	push	ebx
	push	di

	xor	eax, eax

; Clear the common bulk transaction structure
	call	USBM_ClearMassBuffers
; DI	Mass command buffer
	mov	(CommonInquiryCommand PTR [di]).OpCode, COMMON_INQUIRY_OPCODE
	mov	(CommonInquiryCommand PTR [di]).AllocLength, 024h

; Fill the common bulk transaction structure
	mov	stMassXactStruc.bCmdSize, SIZE CommonInquiryCommand
	mov	stMassXactStruc.bXferDir, BIT7	; IN
	push	ds
	pop	ax
	shl	eax, 16
	mov	ax, OFFSET aMassDataBuffer
	mov	stMassXactStruc.fpBuffer, eax
; Allocation Length = 36 bytes
	mov	stMassXactStruc.dwLength, 024h
	call	USBM_IssueMassTransaction
	jz	UMIC_Exit

; Clear the cached block size
        mov	stMassDeviceInfo.wBlockSize, 0FFFFh

; Check for CDROM
	mov	di, OFFSET aMassDataBuffer
; Set the type as CDROM and emulation as HDD or FDD
	mov	al, USB_MASS_DEV_CDROM
	cmp	BYTE PTR DS:[di], 5
	je	UMIC_Done
	xor	ax, ax
UMIC_Done:
	mov	stMassDeviceInfo.bDevType, al
; Mark as success
	or	sp, sp
UMIC_Exit:
	pop	di
	pop	ebx
	pop	eax
	ret

USBM_InquiryCommand 	ENDP
EndComment ~

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	USBM_StartUnitCommand
;
; Description:	This function sends the start unit command to the mass device
;
; Input: 	None
;
; Output: 	ZR	On failed completion
;		NZ	On successful completion
;
; Modified:	Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

USBM_StartUnitCommand 	PROC NEAR SYSCALL PUBLIC

	push	di

; Check the compatibility flag for start unit command not supported
	test	CurrentDevice.wIncompatFlags, USB_INCMPT_START_UNIT_NOT_SUPPORTED
	jnz	UMSUC_Exit

	call	USBM_ClearMassBuffers
; DI	Mass command buffer
	mov	(CommonStartStopUnitCommand PTR [di]).OpCode,  \
						COMMON_START_STOP_UNIT_OPCODE
	mov	(CommonStartStopUnitCommand PTR [di]).Start,  1

; Fill the common bulk transaction structure
	mov	stMassXactStruc.bCmdSize, SIZE CommonStartStopUnitCommand
	call	USBM_IssueMassTransaction
	jnz	UMSUC_Exit
; No data to read/write. So do not process return code.
; Request sense
	call	USBM_RequestSense
	cmp	sp, sp		; Return error
UMSUC_Exit:
	pop	bx
	ret

USBM_StartUnitCommand 	ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	USBM_ModeSense
;
; Description:	This function requests the mode sense data page number 5 from
;		the USB mass storage device
;
; Input: 	None
;
; Output: 	ZR	On failed command completion
;		NZ	On successful command completion
;
; Modified:	Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

USBM_ModeSense 	PROC NEAR SYSCALL PUBLIC

	push	eax
	push	di

; Set return value as failure
	xor	ax, ax

	call	USBM_ClearMassBuffers
; DI	Mass command buffer
; Load command into (just allocated) mass command buffer
	mov	(CommonModeSense10Command PTR [di]).OpCode,  \
						COMMON_MODE_SENSE_10_OPCODE

; Allocation Length = 40 bytes
	mov	ah, 028h		; MSB in low byte
	mov	(CommonModeSense10Command PTR [di]).AllocLength, ax

; Page code
	mov	(CommonModeSense10Command PTR [di]).PageCode, 5

; Fill the common bulk transaction structure
	mov	stMassXactStruc.bCmdSize, SIZE CommonModeSense10Command
	mov	stMassXactStruc.bXferDir, BIT7
	push	ds
	pop	ax
	shl	eax, 16
	mov	ax, OFFSET aMassDataBuffer
	mov	stMassXactStruc.fpBuffer, eax
	mov	stMassXactStruc.dwLength, 028h
	call	USBM_IssueMassTransaction
	jz	UMPMS_FreeExit

	mov	di, OFFSET aMassDataBuffer
; Store media type byte
	mov	al, (MODE_SENSE_10_HEADER PTR [di]).bMediaType
	mov	stMassDeviceInfo.bMediaType, al

; Position DI to the correct page code starting location
	mov	ax, (MODE_SENSE_10_HEADER PTR [di]).wBlkDescSize
	add	ax, SIZE MODE_SENSE_10_HEADER
	add	di, ax

; DI	Points to the page code 5 data
; Validate mode sense data
	cmp	(PAGE_CODE_5 PTR [di]).bPageCode, 5
	je	UMPMS_ValidPageCode

	cmp	sp, sp		; Set zero flag
UMPMS_FreeExit:
; Request sense
	call	USBM_RequestSense
	jmp	SHORT UMPMS_Exit

UMPMS_ValidPageCode:
	
; Store bytes per sector
	mov	ax, (PAGE_CODE_5 PTR [di]).wBlockSize
	xchg	ah, al				; Change to big endian
	mov	stMassDeviceInfo.wBlockSize, ax
	
; Store heads/sector information
; Heads/sectors	
	mov	ax, WORD PTR (PAGE_CODE_5 PTR [di]).bHeads
	mov	stMassDeviceInfo.bSectors, ah
	mov	stMassDeviceInfo.bHeads, al

	mov	ax, (PAGE_CODE_5 PTR [di]).wCylinders
	xchg	ah, al				; Change to big endian
	mov	stMassDeviceInfo.wCylinders, ax

; Set the appropriate command flag
	or	wUSBCommandStatus, USB_CMDSTS_MODE_SENSE_DONE

; Mark as success
	or	sp, sp		; Clear zero flag

UMPMS_Exit:
	pop	di
	pop	eax
	ret
USBM_ModeSense 	ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	USBM_RequestSense
;
; Description:	This function sends request sense command and returns
;		the sense key information
;
; Input: 	None
;
; Output: 	ZR	On error
;		NZ	On successful completion
;
; Modified:	Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

USBM_RequestSense 	PROC NEAR SYSCALL PUBLIC

	push	eax
	push	di

	xor	eax, eax
	dec	eax
	mov	dLastSenseData, eax

	call	USBM_ClearMassBuffers
; DI	Mass command buffer
	mov	(CommonRequestSenseCommand PTR [di]).OpCode,  COMMON_REQUEST_SENSE_OPCODE
; Length of transfer
	mov	(CommonRequestSenseCommand PTR [di]).AllocLength, 12h

; Fill the common bulk transaction structure
	mov	stMassXactStruc.bCmdSize, SIZE CommonRequestSenseCommand
	mov	stMassXactStruc.bXferDir, BIT7
	push	ds
	pop	ax
	shl	eax, 16
	mov	ax, di
	mov	stMassXactStruc.fpBuffer, eax
	mov	stMassXactStruc.dwLength, 012h
	call	USBM_IssueMassTransaction

⌨️ 快捷键说明

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