📄 usbmbb.asm
字号:
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 + -