📄 usbmass.asm
字号:
; Size of the device in EAX in MB
cmp eax, MAX_SIZE_FOR_FLOPPY_EMULATION
jbe UMIDT_DeviceTypeOver
; Assume as HDD
mov cx, (USB_EMU_HDD_ONLY SHL 8) + USB_MASS_DEV_HDD
UMIDT_DeviceTypeOver:
; Update mass info structure with device and emulation type
mov (MassDeviceInfo PTR [bx]).bDevType, cl
mov (MassDeviceInfo PTR [bx]).bEmuType, ch
; Restore BX
pop bx
pop ecx
pop eax
ret
USBMassIdentifyDeviceType ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBMassConsumeBulkData
;
; Description: This function reads unwanted amount of data specified in
; the size
;
; Input: SI Pointer to DeviceInfo structure
; CX Amount of data to be consumed
; DL Transfer direction
;
; Output: ZR On error
; NZ On successfull completion
;
; Modified: None
;
; Referrals: DeviceInfo
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBMassConsumeBulkData PROC NEAR SYSCALL
push eax
push bx
push ecx
push di
push es
; Need to process only maximum amount of data that pUSBMassConsumeBuffer can
; handle, i.e. MAX_CONTROL_DATA_SIZE
UMCBT_NextDataTransport:
mov bx, cx
cmp bx, MAX_CONTROL_DATA_SIZE
jb UMCBT_SizeOkay
mov bx, MAX_CONTROL_DATA_SIZE
UMCBT_SizeOkay:
; Set ES:DI to consume buffer
push ds
pop es
mov di, pUSBMassConsumeBuffer
push cx
; Consume buffer size
movzx ecx, bx
; SI DeviceInfo Structure
; ES:DI Pointer to the data buffer
; ECX Size of data to be tranferred
; DL Transaction direction
call USBMiscIssueBulkTransfer
pop cx
; EAX = Size. Comparing AX should be sufficient
cmp ax, bx
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 es
pop di
pop ecx
pop bx
pop eax
ret
USBMassConsumeBulkData ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBMassProcessBulkData
;
; 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: SI Pointer to DeviceInfo structure
; DI Pointer to MassDeviceInfo structure
; 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: EAX Amount of data actually transferred
;
; Modified: EAX
;
; Referrals: HCStruc, DeviceInfo
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBMassProcessBulkData PROC NEAR SYSCALL PUBLIC
push cx
push dx
push di
push es
; 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
; Check whether something we have to transfer
cmp stMassXactStruc.dwLength, 0
je UMPBD_Exit
; 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 USBMassConsumeBulkData
jz UMPBD_Exit ; Error ? Exit !
UMPBD_NoPreSkipBytes:
push wTimeOutValue ; Save original value
; Check the bulk data delay specified
mov ax, wBulkDataXferDelay
or ax, ax
je UMPBD_NoExtraDelay
; Extra delay needed
mov wTimeOutValue, ax
UMPBD_NoExtraDelay:
les di, stMassXactStruc.fpBuffer
test stMassXactStruc.wMiscFlag, USBM_XACT_FLAG_32BIT_DATA_BUFFER
jz UMPBD_BufPtrDone
mov edi, stMassXactStruc.fpBuffer
UMPBD_BufPtrDone:
mov ecx, stMassXactStruc.dwLength
call USBMiscIssueBulkTransfer
; Restore original timeout value
pop wTimeOutValue
mov wBulkDataXferDelay, 0
; EAX actual data size
or eax, eax
je UMPBD_Exit
; Check whether post skip is needed
cmp stMassXactStruc.wPostSkip, 0
je UMPBD_Exit
push eax ; Amount of data actually processed
mov cx, stMassXactStruc.wPostSkip
call USBMassConsumeBulkData
pop eax
; Since we already read the requested number of bytes it does not matter
; whether the post skip read is successful or not
UMPBD_Exit:
pop es
pop di
pop dx
pop cx
ret
USBMassProcessBulkData ENDP
; DS:BX String to be adjustes
; Destroys nothing
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBMassAdjustIdString
;
; Description: This function forms the vendor/device identification string
; from the data obtained from the USB device
;
; Input: DS:BX Pointer to the string obtained from the USB device
;
; Output: DS:BX Vendor/device string formed
;
; Modified: BX
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBMassAdjustIdString PROC NEAR SYSCALL PUBLIC
push ax
push cx
push di
push bx
; The string contains 8 bytes of vendor id + 32 byte of device id
; Shorten the vendor id if it has more spaces
mov di, bx
; Set destination string one byte below the current string
dec di
; Initialize the variables
xor cx, cx
; CH Flag indicating whether Vendor id is copied or not
; CL Vendor id length
UMAIS_NextByte:
mov al, BYTE PTR [bx]
; Check for end of the string
or al, al
je UMAIS_Done
; Check whether it is space
cmp al, ' ' ; 20h
jne UMAIS_JustCopy
; Check whether we already copied the vendor id
or ch, ch
jnz UMAIS_CheckForMoreSpaces
; Skip the remaining spaces
push ax
mov al, 8
sub al, cl
movzx ax, al
dec al
add bx, ax
pop ax
inc ch
jmp SHORT UMAIS_JustCopy
UMAIS_CheckForMoreSpaces:
cmp BYTE PTR [bx+1], ' '
je UMAIS_Done
UMAIS_JustCopy:
mov BYTE PTR [di], al
inc bx
inc di
inc cl
cmp cl, 8
jne UMAIS_NextByte
or ch, ch
jnz UMAIS_NextByte
; Vendor id is 8 characters long. Insert a space.
mov BYTE PTR [di], ' '
inc di
jmp SHORT UMAIS_NextByte
UMAIS_Done:
; Add a space & null character
mov WORD PTR [di], 0020h
pop bx
dec bx
pop di
pop cx
pop ax
ret
USBMassAdjustIdString ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBMassInquiryCommand
;
; Description: This function sends inquiry command to the USB mass storage
; device
;
; Input: SI Pointer to DeviceInfo structure
;
; Output: ZR On error
; NZ On successfull completion
; DI Pointer to the inquiry data
;
; Modified: None
;
; Referrals: HCStruc, DeviceInfo
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBMassInquiryCommand PROC NEAR SYSCALL PUBLIC
push eax
push ebx
push di
; Allocate memory for the command buffer
call USBMem_AllocOne
jz UMIC_Exit
; Load command into (just allocated) mass command buffer
mov di, ax
mov (CommonInquiryCommand PTR [di]).OpCode, COMMON_INQUIRY_OPCODE
mov (CommonInquiryCommand PTR [di]).AllocLength, 024h
; Clear the common bulk transaction structure
call USBMassClearMassXactStruc
; Fill the common bulk transaction structure
mov stMassXactStruc.pCmdBuffer, di
mov stMassXactStruc.bCmdSize, SIZE CommonInquiryCommand
mov stMassXactStruc.bXferDir, BIT7 ; IN
push ds
pop ax
shl eax, 16
mov ax, pUSBTempBuffer
add ax, 40h ; Use later portion of the buffer
mov stMassXactStruc.fpBuffer, eax
; Allocation Length = 36 bytes
mov stMassXactStruc.dwLength, 024h
call USBMassIssueMassTransaction
or eax, eax
jz UMIC_FreeExit
; Mark as success
or sp, sp
UMIC_FreeExit:
pushf
; Check and free command buffer
mov bx, di
call USBMem_FreeOne
popf
UMIC_Exit:
pop di
; Return the pointer to the inquiry data
mov di, pUSBTempBuffer
add di, 40h ; Use later portion of the buffer
pop ebx
pop eax
ret
USBMassInquiryCommand ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBMassRWVCommand
;
; Description: This function reads/writes/verifies blocks of data from the
; USB mass device specified by its device address
;
; Input: SI Pointer to DeviceInfo structure
; DL Read/Write/Verify
; ES:BX Pointer to the read command structure
; bDevAddr USB device address of the device
; dStartLBA Starting LBA address
; wNumBlks Number of blocks to process
; wPreSkipSize Number of bytes to skip before
; wPostSkipSize Number of bytes to skip after
; fpBufferPtr Far buffer pointer
;
; Output: AX Return code (0 - Failure, <>0 - Size read)
; fpReadData Pointer to the mass read command structure
; dSenseData Sense data of the last command
; fpBufferPtr Far buffer pointer
;
; Modified: AX
;
; Referrals:
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBMassRWVCommand PROC NEAR SYSCALL PUBLIC
push bx
push ecx
push dx
push di
push fs
; Set return value as failure
xor ax, ax
xor dh, dh
mov di, ax
mov fs, ax
; Set command not retried (BIT0 in DH)
and dh, BIT0
; Set the sense code as 0
mov (MASS_READ PTR ES:[bx]).dSenseData, eax
; Allocate memory for the command buffer
call USBMem_AllocOne
jz UPRCC_Exit
; Load command into (just allocated) mass command buffer
mov di, ax
; Save SI
mov cx, si
; Set SI to mass info buffer
mov si, (DeviceInfo PTR [si]).pMassInfoPtr
mov (CommonRWVCommand PTR [di]).OpCode, dl
mov eax, (MASS_READ PTR ES:[bx]).dStartLBA
; If the "Forced FDD" option is selected that means the device has
; to be emulated as a floppy drive even though it has a HDD emulated
; image. This is accomplished by hiding the first cylinder totally.
; The partition table is in the first cylinder. LBA value for all
; the requests to the device will be offset with the number of sectors
; in the cylinder.
; Check for forced floppy emulated device and change LBA accordingly
cmp (MassDeviceInfo PTR [si]).bEmuType, \
USB_EMU_FORCED_FDD
jne UPRCC_NotZIPFloppy
; Skip first track in case of floppy emulation
push ebx
movzx ebx, (MassDeviceInfo PTR [si]).bHiddenSectors
add eax, ebx
pop ebx
UPRCC_NotZIPFloppy:
; Change big endian format (INTEL) to little endian format
xchg ah, al
rol eax, 16
xchg ah, al
mov (CommonRWVCommand PTR [di]).Lba, eax
UPRCC_RetryCommand:
; Check the validity of the block size
cmp (MassDeviceInfo PTR [si]).wBlockSize, 0FFFFh
jne UPRCC_GetSize
; Update the device geometry
; Get the device info value in SI
mov si, cx
jmp UPRCC_ProceedIfRW
UPRCC_GetSize:
mov ax, (MASS_READ PTR ES:[bx]).wNumBlks
push ax
; Change big endian format (INTEL) to little endian format
xchg ah, al
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -