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

📄 usbmass.asm

📁 dos下的USB源码(包括UHCI
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	mov	eax, DWORD PTR [di+4]
	xchg	ah, al
	rol	eax, 16
	xchg	ah, al
        mov	(MassDeviceInfo PTR [bx]).dMaxLBA, eax

; Check for 1.44MB floppy drive
	cmp	eax, USB_144MB_FDD_MAX_LBA
	jne	UMRFC_Cont

; Return parameters for 144MB floppy
	mov	(MassDeviceInfo PTR [bx]).bHeads, USB_144MB_FDD_MAX_HEADS
	mov	(MassDeviceInfo PTR [bx]).bNonLBAHeads, USB_144MB_FDD_MAX_HEADS
	mov	(MassDeviceInfo PTR [bx]).bSectors, USB_144MB_FDD_MAX_SECTORS
	mov	(MassDeviceInfo PTR [bx]).bNonLBASectors, USB_144MB_FDD_MAX_SECTORS
	mov	(MassDeviceInfo PTR [bx]).wCylinders, USB_144MB_FDD_MAX_CYLINDERS
	mov	(MassDeviceInfo PTR [bx]).wNonLBACylinders, USB_144MB_FDD_MAX_CYLINDERS
	mov	(MassDeviceInfo PTR [bx]).bMediaType, USB_144MB_FDD_MEDIA_TYPE

UMRFC_Cont:
	pop	di
; Clear zero flag indicating success
	or	sp, sp

UMRFC_FreeExit:
	pushf
; Check and free command buffer
	mov	bx, di
	call	USBMem_FreeOne
	popf

UMRFC_Exit:
	pop	di
	pop	bx
	pop	eax
	ret
USBMassReadFormatCapacity 	ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	USBMassReadSector
;
; Description:	This function a sector at the LBA specified
;
; Input: 	SI	Pointer to DeviceInfo structure
;		EAX	LBA to read
;		DS:DI	Data buffer
;
; Output: 	ZR	If read failed
;		NZ	If read is successful
;
; Modified:	Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

USBMassReadSector	PROC NEAR SYSCALL
	push	eax
	push	bx
	push	edx

	mov	edx, eax

; Allocate memory for the command buffer
	call	USBMem_AllocOne
	jz	UMRS_Exit
	mov	bx, ax

; Set opcode to read command
	mov	(CommonRWVCommand PTR [bx]).OpCode, COMMON_READ_10_OPCODE
; Number of blocks (sectors to read)
	mov	ax, 1
	xchg	ah, al		; Big endian to little endian
	mov	(CommonRWVCommand PTR [bx]).TransferLength, ax

	mov	eax, edx
	xchg	ah, al		; Big endian to little endian
	rol	eax, 16
	xchg	ah, al
	mov	(CommonRWVCommand PTR [bx]).Lba, eax

	xor	dx, dx		; DX = 0

UMRS_RetryCommand:
; Fill the common bulk transaction structure
; Fill Command buffer address & size
	mov	stMassXactStruc.pCmdBuffer, bx
	mov	stMassXactStruc.bCmdSize, SIZE CommonRWVCommand
	mov	stMassXactStruc.bXferDir, BIT7		; IN
	push	ds
	push	di
	pop	eax
	mov	stMassXactStruc.fpBuffer, eax
	mov	stMassXactStruc.dwLength, 200h		; 512 bytes
	xor	ax, ax
	mov	stMassXactStruc.wPreSkip, ax
	mov	stMassXactStruc.wPostSkip, ax
	call	USBMassIssueMassTransaction
	or	eax, eax
	jnz	UMRS_SuccessfulRead

; May be drive error. Try to correct from it !
; Check whether the drive is ready for read/write/verify command
; SI	DeviceInfo
	call	USBMassCheckDeviceReady
	or	eax, eax
	jnz	UMRS_SkipNotSuccess

; Retry the command
	or	dl, dl
	jnz	UMRS_SkipNotSuccess
	inc	dl
	jmp	UMRS_RetryCommand

UMRS_SkipNotSuccess:
; Set zero flag
	cmp	sp, sp
	jmp	UMRS_FreeExit

UMRS_SuccessfulRead:
	or	sp, sp		; Clear zero flag

UMRS_FreeExit:
	pushf
; Check and free command buffer (in BX)
	call	USBMem_FreeOne
	popf

UMRS_Exit:
	pop	edx
	pop	bx
	pop	eax
	ret
USBMassReadSector	ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	USBMassUpdateCHSFromBootRecord
;
; 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: 	SI	Pointer to DeviceInfo structure
;		ECX	Maximum LBA in the device
;		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>

USBMassUpdateCHSFromBootRecord	PROC NEAR SYSCALL

	push	eax
	push	ecx
	push	dx
	push	si

; 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
	cmp	eax, 'SFTN'			; NTFS
	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:
	mov	si, (DeviceInfo PTR [si]).pMassInfoPtr

	xor	ax, ax
	mov	al, BYTE PTR [di+18h]		; Sectors/track
	mov	(MassDeviceInfo PTR [si]).bSectors, al
	mov	(MassDeviceInfo PTR [si]).bNonLBASectors, al
	mov	al, BYTE PTR [di+1Ah]		; heads
	mov	(MassDeviceInfo PTR [si]).bHeads, al
	mov	(MassDeviceInfo PTR [si]).bNonLBAHeads, al

	mul	(MassDeviceInfo PTR [si]).bSectors
	xchg	eax, ecx
	push	eax
	pop	ax
	pop	dx
	div	cx
	mov	(MassDeviceInfo PTR [si]).wCylinders, ax
	mov	(MassDeviceInfo PTR [si]).wNonLBACylinders, ax

	or	sp, sp
UMUCFBR_Exit:
	pop	si
	pop	dx
	pop	ecx
	pop	eax
	ret
USBMassUpdateCHSFromBootRecord	ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	USBMassGetFormatType
;
; Description:	This function reads the first sector from the mass storage
;		device and identifies the formatted type.
;
; Input: 	SI	Pointer to DeviceInfo structure
;		EAX	Maximum LBA in the device
;
; Output: 	ZR	If could not identify the formatted type
;		NZ	If formatted type is identified
;		  CH	Emulation type
;		  CL	Device type (Floppy, Harddisk or CDROM)
;
; Modified:	ECX
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

USBMassGetFormatType		PROC NEAR SYSCALL PUBLIC

	push	eax
	push	bx
	push	dx
	push	di

; Save CX in DX
	mov	dx, cx

	mov	ecx, eax
;; #1.  Read the first sector of the device

; Set the LBA number to 0
	xor	eax, eax
	mov	di, pUSBMassConsumeBuffer
	call	USBMassReadSector
	jz	UMGFT_Exit

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

;; #2. 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
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

; Valid partition table found. 
;; #3. If it has valid partition table then
;; #4.   Check number of entries in the partition table
;; #10.   If the number of entries is not equal to 1 then assume HDD and leave
	cmp	ah, 1
	ja	UMGFT_HDDEmulation
	jb	UMGFT_InvalidPartitionTable

; Only one partition present, check the device size, 
	cmp	ecx, MAX_LBA_FOR_FLOPPY_EMULATION
; if the device size is less than 530 MB assume FDD or else assume the
; emulation as HDD
	ja	UMGFT_HDDEmulation

	mov	ax, dx
;; #5.   If the number of entries is 1 then
;; #6.     Assume emulation as Forced FDD
; Assume emulation as Forced FDD.
	mov	dx, (USB_EMU_FORCED_FDD SHL 8) + USB_MASS_DEV_ARMD
;;; Assume emulation as HDD
;;	mov	dx, (USB_EMU_HDD_ONLY SHL 8) + USB_MASS_DEV_HDD

; Read boot sector
; Set the LBA number to boot record LBA number
	mov	di, pUSBMassConsumeBuffer
	push	di
	mov	di, ax
	mov	eax, DWORD PTR [di+8]
	pop	di
; Save hidden sector value
	push	si
	mov	si, (DeviceInfo PTR [si]).pMassInfoPtr
	mov	(MassDeviceInfo PTR [si]).bHiddenSectors, al
	pop	si
	call	USBMassReadSector
	jz	UMGFT_Exit

;; #7.       If boot record is a valid FAT/NTFS file system 
;; #8.         Get CHS value from the boot record and leave
;; #9.       Else Assume emulation type as HDD and leave
; DS:DI	Boot record
	call	USBMassUpdateCHSFromBootRecord
	jnz	UMGFT_EmulationFound
	jmp	SHORT UMGFT_HDDEmulation

UMGFT_InvalidPartitionTable:
;; #11. Else 
;; #12.   Assume emulation type as FDD
; Assume the emulation as floppy
	mov	dx, (USB_EMU_FLOPPY_ONLY SHL 8) + USB_MASS_DEV_ARMD
						;(USB001+)>
;Check whether UFI class device
	push	si
	mov	si, (DeviceInfo PTR [si]).pMassInfoPtr
	cmp	(MassDeviceInfo PTR [si]).bSubClass, SUB_CLASS_UFI
	pop	si
	jz	UMGFT_SkipPatchForUFI
;Assume force FDD emulation for non-UFI class device
	mov	dx, (USB_EMU_FORCED_FDD SHL 8) + USB_MASS_DEV_ARMD
UMGFT_SkipPatchForUFI:
						;<(USB001+)
;; #13.   If boot record is a valid FAT/NTFS file system
;; #14.     Get CHS value from the boot record and leave
	mov	di, pUSBMassConsumeBuffer
	call	USBMassUpdateCHSFromBootRecord
	jnz	UMGFT_EmulationFound

;; #15.   Else
;; #16.     Check the device size
	cmp	ecx, MAX_LBA_FOR_FLOPPY_EMULATION
;; #17.     If the device size is less than 530 MB assume FDD and leave
	jb	UMGFT_EmulationFound
;; #18.     ELSE assume as HDD and leave
UMGFT_HDDEmulation:
; Reset hidden sector value
	mov	(MassDeviceInfo PTR [si]).bHiddenSectors, 0
; Assume the emulation as HDD
	mov	dx, (USB_EMU_HDD_ONLY SHL 8) + USB_MASS_DEV_HDD

UMGFT_EmulationFound:
	mov	cx, dx
; Clear the carry flag indicating success
	or	sp, sp		; 
	jmp	SHORT UMGFT_Exit

UMGFT_SkipNotSuccess:
	mov	cx, dx		; Restore CX
; Set zero flag
	cmp	sp, sp

UMGFT_Exit:
	pop	di
	pop	dx
	pop	bx
	pop	eax
	ret

USBMassGetFormatType		ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	USBMassIdentifyDeviceType
;
; Description:	This function identifies the type of the USB mass storage
;		device attached from the INQUIRY data obtained from the drive
;
; Input: 	SI	Pointer to DeviceInfo structure
;		DI	Pointer to the inquiry data (read from device)
;
; Output: 	Nothing
;
; Modified:	None
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

USBMassEmulationTypeTable	LABEL	WORD
	WORD	(USB_EMU_FLOPPY_ONLY SHL 8) + USB_MASS_DEV_ARMD
	WORD	(USB_EMU_FORCED_FDD SHL 8) + USB_MASS_DEV_ARMD
	WORD	(USB_EMU_HDD_ONLY SHL 8) + USB_MASS_DEV_HDD	
	WORD	(USB_EMU_HDD_OR_FDD SHL 8) + USB_MASS_DEV_CDROM

USBMassIdentifyDeviceType	PROC NEAR SYSCALL PUBLIC

	push	eax
	push	ecx
	push	bx

; Get MassDeviceInfo structure pointer into BX
	mov	bx, (DeviceInfo PTR [si]).pMassInfoPtr

; Get the emulation type setup option
	mov	ax, (MassDeviceInfo PTR [bx]).wEmulationOption
	call	check_cmos_data_far
	or	al, al
	jz	UMIDT_EmuTypeAuto
	dec	ax
	shl	ax, 1		; Multiply by 2
	add	ax, OFFSET USBMassEmulationTypeTable
	push	bx
	mov	bx, ax
	mov	cx, WORD PTR CS:[bx]
	pop	bx
	jmp	SHORT UMIDT_DeviceTypeOver
	
UMIDT_EmuTypeAuto:
; Get the device type from the inquiry data
	mov	al, BYTE PTR [di]

; Get the sub-class type of the mass device
	mov	ah, (MassDeviceInfo PTR [bx]).bSubClass

; It is a removable device. Check for CDROM drive type
	cmp	al, 05h
	jne	UMIDT_CheckWithGeometry

UMIDT_SetCDROMType:
; Set the type as CDROM and emulation as HDD or FDD
	mov	cx, (USB_EMU_HDD_OR_FDD SHL 8) + USB_MASS_DEV_CDROM
	jmp     UMIDT_DeviceTypeOver

UMIDT_CheckWithGeometry:

; Assume as floppy
	mov	cx, (USB_EMU_FLOPPY_ONLY SHL 8) + USB_MASS_DEV_ARMD

; Device is coming up give some delay
	push	ax		; Sense code
	mov	ax, ((500 * 1000) / 15)	; 500ms delay
	call	USBMisc_FixedDelay
	pop	ax		; Sense code

; Get the block size & last LBA number
; SI 	Pointer to the device info structure
	call	USBMassCheckDeviceReady

; Check for media presence status
	cmp	eax, 003A02h
	jne	UMIDT_ProceedNormalChecking

; Check the compatibility flag for format capacity command not supported
	test	(DeviceInfo PTR [si]).wIncompatFlags, USB_INCMPT_FORMAT_CAPACITY_NOT_SUPPORTED
	jnz	UMIDT_ProceedNormalChecking

; Media not present. Try to get disk geometry from Format capacity command
	call	USBMassReadFormatCapacity
	jmp	SHORT UMIDT_DeviceTypeOver

UMIDT_ProceedNormalChecking:
	or	eax, eax
	jnz	UMIDT_DeviceTypeOver		; Assume as floppy

; Get the max LBA & block size
	mov	ax, (MassDeviceInfo PTR [bx]).wBlockSize

; If block size is other than 512 bytes assume emulation as CDROM
	cmp	ax, 200h
	ja	UMIDT_SetCDROMType

; Read the first sector and verify the emulation type
	mov	eax, (MassDeviceInfo PTR [bx]).dMaxLBA
	call	USBMassGetFormatType	; EAX - dMaxLBA
	jnz	UMIDT_DeviceTypeOver	; Device type identified

; Find the device type by size
	push	cx
	mov	cl, (20 - 9)		; 512 / (1024 * 1024)
	shr	eax, cl
	pop	cx

⌨️ 快捷键说明

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