fcmsea
驱动牛犊
驱动牛犊
  • 注册日期2002-05-04
  • 最后登录2006-04-10
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
阅读:1555回复:2

dos下如何编写usb的驱动?

楼主#
更多 发布于:2003-04-23 13:29
如题。谢谢!
else
驱动小牛
驱动小牛
  • 注册日期2002-10-21
  • 最后登录2004-06-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-04-26 13:12
USB in DOS
Here is a little bit of code to detect the USB ports and the status of these ports. It isn\'t commented much, and no where near complete, but it should help you out a little bit.

Thanks goes to Dieter Pawelczak and Jan Axelson for thier help. Have a look at my books page for Jan\'s book on USB.

This code is not complete and even has a few pascal comments and code. However, it should run under a DOS box and display the PCI version, and all Root Hubs connected to it.

However, please take into consideration that I do not take any responibility for what this code may or may not do. It has not been tested on more than one machine, so it might be that machine dependant.

This code uses this binary file (required) to identify each item.
It is simply a list of vendors and parameters \"compiled\" from this text file.
Only the first of the two is needed, but you would benefit from them both.

Let me know if you have any questions or comments about this code. I would appreciate any comments and/or documentation that will help the progress of this code. And as you can see, I leave credit where credit is due (smile)


(the following code was assembled with NBASM v24.9x)


; =-=-=-=-=-=-=-=-=- CUT HERE -=-=-=-=-=-=-=-=-=
;
; assembled with NBASM v24.9x
;  http://www.cybertrails.com/~fys/newbasic.htm
;
; I suggest you don\'t run this program with anything plugged in to the root hubs.
;  This program tends to confuse the items, and they go into a reset loop....
;
;
.model tiny
.code
.386P

; =-=-=-=-=- includes
include usb.inc  ; <---- see below

           org  100h

; =-=-=-=-=- resize memory, etc.
           .start

; =-=-=-=-=- Make sure is .386+
           ;;;;;;

; this part is commented out.  It will not run in a DOS window under Windows.
; =-=-=-=-=- Detect V86 mode
;           smsw ax                      ; store machine status word (.386P !!)
;           and  ax,1                    ;
;           jz   short notv86mode        ;
;           mov  si,offset v86_mode_s    ;
;           call prtstring               ;
;           .exit                        ;
;notv86mode:

; =-=-=-=-=- Startup string
; print startup string here.  (Cosmetic)

; =-=-=-=-=- Print detect string
           mov  si,offset DetectS       ; print finding PCI BIOS
           call prtstring               ;

; =-=-=-=-=- Detect PCI BIOS
           mov  ax,0B101h               ; Detect PCI BIOS
           int  1Ah                     ; on return bh:bl = version (BCD)
           jnc  short FoundPCI          ;
           mov  si,offset PCIBoisNS     ; not found, so post
           call prtstring               ;
           .exit 1                      ;  and exit with RC = 1

; =-=-=-=-=- Found PCI BIOS
FoundPCI:  mov  si,offset PCIBoisFS     ; found it, cont.
           call prtstring               ;
           xor  ah,ah                   ;
           mov  al,bh                   ;
           call PrtHexN                 ; print major version
           mov  ah,02                   ;
           mov  dl,\'.\'                  ;  .
           int  21h                     ;
           xor  ah,ah                   ;
           mov  al,bl                   ;
           call PrtHexN                 ; print minor version


; =-=-=-=-=- Find USB devices
           mov  word dev_index,00h      ; start with 0
FindUSBL:  call FindUSB                 ;
           or   ah,ah                   ; if ah = !0, then no more
           jnz  short usb_done          ;

           ;;;; if IOAddr < 100h then write to port + 20h = 120h ???

; =-=-=-=-=- Try to enable current PCI port found
           mov  si,offset enable_s      ;
           call prtstring               ;
           call pci_enable              ; enable PCI->USB port
           jnc  short pci_enable_good   ;
           mov  si,offset e_bad_s       ; print bad_enable string
           call prtstring               ;
           .exit                        ;  and exit to DOS
pci_enable_good:                        ;
           mov  si,offset e_good_s      ;
           call prtstring               ;

; =-=-=-=-=- Allocate Frame List Buffer
           mov  dx,IOAddr               ; dx -> IOaddr space
           call alloc_f_list            ;
           jnc  short frame_ok          ;
           mov  si,offset no_memory_s   ;
           call prtstring               ;
           jmp  short usb_get_next      ;
frame_ok:                               ;

; =-=-=-=-=- Try to enable all USB ports on current hub (1 and 2)
           mov  dx,IOAddr               ; dx -> IOaddr space
           call usb_enable              ; enable USB ports

; =-=-=-=-=- Get/Print status of current PCI port found
           mov  dx,IOAddr               ; dx -> IOaddr space
           call usb_status              ; print status


; does nothing, yet.  I got to here with my research
;  and have yet to come back to it. :-)
           call get_dev_id
        

; =-=-=-=-=- get int number
;           call usb_get_int_num

; ditto



usb_get_next:
           inc  word dev_index          ;
           jmp  short FindUSBL          ; continue on to next device
usb_done:

           .exit


;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; finds a USB card/hub on given PCI index
; on entry:
;  dev_index = index
; on exit:
;  ah = 00h if card found
FindUSB    proc near uses bx cx dx si di

           mov  si,dev_index
           mov  ax,0B103h               ; find PCI CLASS
           mov  ecx,000C0300h           ; (USB = base=C, sub=3)
           int  1Ah                     ;
           jnc  short UFoundOne         ; on return: bh = bus
           mov  ah,01                   ;            bl = dev num/func num
           ret                          ;

UFoundOne: mov  si,offset FoundUSBTS    ; print found USB controller
           call prtstring               ;

           mov  bus_num,bh              ; save bus/dev/function
           mov  dev_func,bl             ;

           xor  di,di                   ; read word at 0000h (Vendor ID)
           call ReadPCIW                ; read it (returns in AX)
           mov  VendorID,ax             ; save it
           mov  di,02h                  ; read word at 0002h (Device ID)
           call ReadPCIW                ; read it (returns in AX)
           mov  DeviceID,ax             ; save it
           call dev_names               ; get vendor and device names
           mov  si,offset VendorIDS     ;
           call prtstring               ;
           mov  ax,VendorID             ;
           call prthex                  ; print VendorID
           mov  si,offset Vendor_N      ; print vendor name
           call prtstring               ;
           mov  si,offset DeviceIDS     ; print device type
           call prtstring               ;
           mov  ax,DeviceID             ;
           call prthex                  ; print DeviceID
           mov  si,offset Device_N      ; print device name
           call prtstring               ;

           mov  si,offset BusNumberS    ;
           call prtstring               ;
           mov  al,bus_num              ; bh = Bus Number
           xor  ah,ah                   ;
           call prthex                  ; print Bus Number
           mov  dl,\'/\'                  ; print a slash
           mov  ah,06                   ;
           int  21h                     ;
           mov  al,dev_func             ; bl = Dev Number
           shr  al,03                   ;  (bits 7-3)
           xor  ah,ah                   ;
           call prthex                  ; print Dev Number
           mov  dl,\'/\'                  ; print a slash
           mov  ah,06                   ;
           int  21h                     ;
           mov  al,dev_func             ; bl = Func Number
           and  al,00000111b            ;  (bits 2-0)
           xor  ah,ah                   ;
           call prthex                  ; print Func Number
           mov  si,offset CommandRS
           call prtstring
           mov  di,04h                  ; read word at 0004h (Command Reg)
           call ReadPCIW                ; read it (returns in AX)
           call prthex                  ;
           mov  si,offset StatusRS
           call prtstring
           mov  di,06h                  ; read word at 0006h (Status Reg)
           call ReadPCIW                ; read it (returns in AX)
           call prthex                  ;
           mov  si,offset RevisionS
           call prtstring
           mov  di,08h                  ; read byte at 0008h (Revision Byte)
           call ReadPCIB                ; read it (returns in AX)
           call prthexn                 ;
           mov  si,offset ClassCodeS
           call prtstring
           mov  di,0Bh                  ; read byte at 000Bh (Class)
           call ReadPCIB                ; read it (returns in AX)
           call prthexn                 ;
           mov  dl,\'/\'                  ; print a slash
           mov  ah,06                   ;
           int  21h                     ;
           dec  di                      ; read byte at 000Ah (Sub Class)
           call ReadPCIB                ; read it (returns in AX)
           call prthexn                 ;
           mov  dl,\'/\'                  ; print a slash
           mov  ah,06                   ;
           int  21h                     ;
           dec  di                      ; read byte at 0009h (Program Inter.)
           call ReadPCIB                ; read it (returns in AX)
           call prthexn                 ;
           mov  si,offset CacheS        ;
           call prtstring               ;
           mov  di,0Ch                  ; read byte at 000Ch (Cache Line Size)
           call ReadPCIB                ; read it (returns in AX)
           call prthexn                 ;
           mov  si,offset BusLatS       ;
           call prtstring               ;
           mov  di,0Dh                  ; read byte at 000Dh (Bus Latency)
           call ReadPCIB                ; read it (returns in AX)
           call prthexn                 ;
           mov  si,offset HeaderS
           call prtstring
           mov  di,0Eh                  ; read byte at 000Eh (Header Type)
           call ReadPCIB                ; read it (returns in AX)
           call prthexn                 ;
           mov  si,offset SelfTestS
           call prtstring
           mov  di,0Fh                  ; read byte at 000Fh (Self Test)
           call ReadPCIB                ; read it (returns in AX)
           call prthexn                 ;
           mov  si,offset IOPortsS
           call prtstring
           ; don\'t do high word???
           ;mov  di,22h                  ; read word at 0022h (base address 4)
           ;call ReadPCIW                ; read it (returns in AX)
           ;call prthex                  ;
           mov  di,20h                  ; read word at 0020h (base address 4)
           call ReadPCIW                ; read it (returns in AX)
           and  ax,0FFFEh               ; clear bit 0 ???
           mov  IOAddr,ax               ; save if for testing the devices
           call prthex                  ;
           push ax                      ; save address space start
           mov  dl,\'-\'                  ;
           mov  ah,02                   ;
           int  21h                     ;
           pop  ax                      ;
           add  ax,31                   ; print address space end
           call prthex                  ;
           mov  si,offset IRQNumS       ;
           call prtstring               ;
           mov  di,3Ch                  ; read byte at 000Fh (IRQ #)
           call ReadPCIB                ; read it (returns in AX)
           call prthexn                 ;
           mov  si,offset IntNumS       ;
           call prtstring               ;
           mov  di,3Dh                  ; read byte at 000Fh (INT #)
           call ReadPCIB                ; read it (returns in AX)
           add  al,09h                  ; (A-D)
           call prthexn                 ;

           mov  ah,00                   ; found one, continue
           ret
FindUSB    endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; on entry
;  dx = io space start
; on exit
;  nothing
usb_status proc near uses all
           mov  si,offset status_str    ;
           call prtstring               ;
           call get_status_reg          ; get status register
           call prthex                  ;

           mov  si,offset cmmnd_str     ;
           call prtstring               ;
           call get_cmmnd_reg           ; get command register
           call prthex                  ;

           mov  si,offset frame_str     ;
           call prtstring               ;
           call get_frame_num           ; get frame number
           call prthex                  ;

           mov  si,offset frameb_str    ;
           call prtstring               ;
           call get_frame_base          ; get frame list base
           ror  eax,16                  ;  print hi word first
           call prthex                  ;
           ror  eax,16                  ;  print lo word last
           call prthex                  ;

           mov  si,offset port0_str     ;
           call prtstring               ;
           call get_port_zero           ; get port 1 (of 2)
           call prthex                  ;
           call prt_port_stat           ; print port status

           mov  si,offset port1_str     ;
           call prtstring               ;
           call get_port_one            ; get port 2 (of 2)
           call prthex                  ;
           call prt_port_stat           ; print port status


; no need to be in usb_status
;           ;;; ??????? reseting registers ???
;           mov  ax,0FFFFh               ; write 0FFFFh to status register
;           call w_status_reg            ;  (clears all bits)


           ret
usb_status endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; on entry
;  ax = portx status register contents
; on exit
;  nothing
prt_port_stat proc near uses dx si
           mov  dx,ax
           and  dx,0001000000000100b   ; extract bits 12 and 2
           test dx,0000000000000100b   ; if bit 2 = 0, then disabled
           jnz  short prt_not_dis      ;
           mov  si,offset port_dis_s   ;
           call prtstring              ;
           ret                         ;
prt_not_dis:
           cmp  dx,0001000000000100b   ; if both set, then suspended
           jne  short prt_not_susp     ;
           mov  si,offset port_susp_s  ;
           call prtstring              ;
           ret                         ;
prt_not_susp:
           mov  si,offset port_enbl_s  ; else must be 0,1 and enabled
           call prtstring              ;

           test ax,0000000000000001b   ; bit 0 = device present (set)
           jnz  short prt_dev_here     ;
           mov  si,offset port_dev_np  ; else a device is not present
           call prtstring              ;
           ret                         ;
prt_dev_here:                          ;
           mov  si,offset port_dev_p   ; device is present
           call prtstring              ;

           mov  si,offset port_low_s   ; assume low speed
           test ax,0000000100000000b   ; bit 8 = low speed (set)
           jnz  short prt_is_low       ;
           mov  si,offset port_full_s  ; else is full speed
prt_is_low:                            ;
           call prtstring              ;

           ret
prt_port_stat endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; Enable the PCI->USB hardware
; on entry
;  nothing
; on exit
;  carry = status
pci_enable proc near uses alld
           mov  di,04h                  ; read word at 0004h (command reg)
           call ReadPCIW                ; read it (returns in AX)
           jc   short no_enable         ;
           push ax                      ; save it
           and  ax,0000000101b          ; bus master enable/io access enable
           cmp  ax,0000000101b          ; are they both already set?
           pop  ax                      ; restore ax
           je   short good_enable       ; yes, so don\'t toggle them
           or   ax,0000000101b          ; no, so set bits 0 and 2, then
           mov  di,04h                  ; write to word at 0004h (command reg)
           call WritePCIW               ; write it
           jc   short no_enable         ;

           ;;; ??? do we need to check to see if enabled as wanted;;;

good_enable:                            ;
           clc                          ; else, good enable
           ret                          ;
no_enable: stc                          ; enable failed
           ret                          ;
pci_enable endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; Enable the current USB port
; on entry
;  dx = io space start (base)
; on exit
;  carry = status
usb_enable proc near uses ax bx
           call get_port_zero           ; returns bits in ax
           mov  bx,ax                   ;
           and  bx,0001000000000100b    ;
           cmp  bx,0001000000000100b    ;
           je   short usb_e_zero        ;
           or   ax,0001000000000100b    ;
           call put_port_zero           ; write ax to port_zero status
usb_e_zero:
           call get_port_one            ; returns bits in ax
           mov  bx,ax                   ;
           and  bx,0001000000000100b    ;
           cmp  bx,0001000000000100b    ;
           je   short usb_e_one         ;
           or   ax,0001000000000100b    ;
           call put_port_one            ; write ax to port_one status
usb_e_one:
           ret
usb_enable endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; on entry
;  dx = io space start (base)
; on exit
;  carry = status
alloc_f_list proc near uses alld es
           xor  eax,eax                 ; clear out high word of eax
           mov  ah,48h                  ; allocate memory
           mov  bx,(8192>4)             ; 8192 bytes
           int  21h                     ;  ax = segment of memory
           jc   short alloc_f_err       ; no memory
           mov  fram_l_bse,ax           ; save it in fram_l_bse for unallocating
           add  ax,0FFh                 ;  place it on a 4k boundary
           and  ax,0FF00h               ;
           shl  eax,4                   ; eax = physical of memory returned
           push eax                     ; save it
           shr  eax,4                   ; convert physical address
           mov  es,ax                   ;  to es:0000
           xor  di,di                   ;  di = 0000
           mov  al,01h                  ; write 1\'s (terminate)
           mov  cx,1024                 ; 1024 bytes
           rep                          ;
           stosb                        ;
           pop  eax                     ; restore physical address
           add  dx,08                   ; dx = io space from caller
           out  dx,eax                  ; store it
           dec  dx                      ; make dx = 06h
           dec  dx                      ;
           xor  ax,ax                   ; write a zero
           out  dx,ax                   ;  to frame number register
           clc                          ; frame is set okay
           ret                          ;
alloc_f_err:                            ;
           stc                          ; no memory
           ret                          ;
alloc_f_list endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; on entry
;  dx = io space start
; on exit
;  
usb_get_int_num proc near uses



           ret
usb_get_int_num endp
;function USBGetInterruptNumber(Var IntNo:word;Var active:boolean):boolean;
;var okay:boolean;
;    command:longint;
;    command2:longint;
;begin
;  okay:=false;
;  active:=false;
;  if isadetected then
;      if readPCIRegisterDWord($60,ISABusNumber,ISAFunctionNumber,command) then
;        begin
;          intno:=command shr 24;
;          active:=intno and 128=0;
;          intno:=intno and 15;
;          okay:=true;
;        end;
;   USBGetInterruptNumber:=okay;
;end;


;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; on entry
;  dx = io starting address
; on exit
;  ax = USB status register contents
get_status_reg proc near uses dx
           inc  dx
           inc  dx                      ; USB status register (base+02)
           in   ax,dx                   ;  word sized
           and  ax,0000000001111111b    ; bits 15-6 reserved
           ret                          
get_status_reg endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; on entry
;  dx = io starting address
; on exit
;  ax = USB command register contents
get_cmmnd_reg proc near uses dx
           in   ax,dx                   ; USB command register (base+00)
           and  ax,0000000011111111b    ; bits 15-8 reserved
           ret
get_cmmnd_reg endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; on entry
;  dx = io starting address
; on exit
;  ax = usb frame number contents
get_frame_num proc near uses dx
           add  dx,06                   ; USB frame register (base+06)
           in   ax,dx                   ;  word sized
           and  ax,0000011111111111b    ; bits 15-11 reserved
           ret
get_frame_num endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; on entry
;  dx = io starting address
; on exit
;  eax = USB frame list base register contents
get_frame_base proc near uses dx
           add  dx,08                   ; USB frame base register (base+08)
           in   eax,dx                  ;  dword sized
           ret
get_frame_base endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; on entry
;  dx = io starting address (base)
; on exit
;  ax = port 1 (of 2) status/control register contents
get_port_zero proc near uses dx
           add  dx,10h                  ; USB port 1 register (base+10h)
           in   ax,dx                   ;  word sized
           and  ax,0001111111111111b    ; bits 15-13 reserved
           ret
get_port_zero endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; on entry
;  dx = io starting address (base)
;  ax = port 1 (of 2) status/control register contents
; on exit
;  ax = port 1 (of 2) status/control register contents after write
put_port_zero proc near uses dx
           add  dx,10h                  ; USB port 1 register (base+10h)
           and  ax,0001111111111111b    ; bits 15-13 reserved
           out  dx,ax                   ; put it
           mov  ax,50                   ; delay for 50 milliseconds
           call delay                   ;
           in   ax,dx                   ;  word sized
           and  ax,0001111111111111b    ; bits 15-13 reserved
           ret
put_port_zero endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; on entry
;  dx = io starting address (base)
; on exit
;  ax = port 2 (of 2) status/control register contents
get_port_one proc near uses dx
           add  dx,12h                  ; USB port 2 register (base+12h)
           in   ax,dx                   ;  word sized
           and  ax,0001111111111111b    ; bits 15-13 reserved
           ret
get_port_one endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; on entry
;  dx = io starting address (base)
;  ax = port 2 (of 2) status/control register contents
; on exit
;  ax = port 2 (of 2) status/control register contents after write
put_port_one proc near uses dx
           add  dx,12h                  ; USB port 2 register (base+12h)
           and  ax,0001111111111111b    ; bits 15-13 reserved
           out  dx,ax                   ; put it
           mov  ax,50                   ; delay for 50 milliseconds
           call delay                   ;
           in   ax,dx                   ;  word sized
           and  ax,0001111111111111b    ; bits 15-13 reserved
           ret
put_port_one endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; on entry
;  dx = io starting address (base)
;  ax = value to write
; on exit
;  nothing
w_status_reg proc near uses dx          ;
           inc  dx                      ; USB status register (base+02)
           inc  dx                      ;
           out  dx,ax                   ; word sized
           ret                          ;
w_status_reg endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; on entry
;  di = byte to read
; on exit
;  ax = byte read (ah = 0)
ReadPCIB   proc near uses bx cx dx si di
           mov  bh,bus_num              ;
           mov  bl,dev_func             ;
           mov  ax,0B108h               ; read word
           int  1Ah                     ;
           mov  al,cl
           xor  ah,ah
           ret
ReadPCIB   endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; on entry
;  di = word to read
; on exit
;  ax = word read
ReadPCIW   proc near uses bx cx dx si di
           mov  bh,bus_num              ;
           mov  bl,dev_func             ;
           mov  ax,0B109h               ; read word
           int  1Ah                     ;
           mov  ax,cx
           ret
ReadPCIW   endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; on entry
;  di = word to write to
;  ax = word to write
; on exit
;  carry = status
WritePCIW  proc near uses bx cx dx si di
           mov  bh,bus_num              ;
           mov  bl,dev_func             ;
           mov  ax,0B10Ch               ; read word
           int  1Ah                     ;
           mov  ax,cx
           ret
WritePCIW  endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
;  opens \'devnums.bin\' and finds a line starting with \'V xxxx\'
;   where xxxx = VendorID.
;  once found, copys the string found after \'V xxxx \' to Vendor_N+3
;   then continues to find \'D xxxx \' where xxxx = DeviceID.
;  if \'V xxxx\' found before device number is found, then error.
;  if number is found, then copies to Device_N+3
dev_names  proc near uses all es

           push cs                      ; make sure es = cs
           pop  es                      ;

           mov  ax,3D00h                ; open for read only
           mov  dx,offset devfile       ;
           int  21h                     ;
           jc   short dev_names_d       ;
           mov  bx,ax                   ;
           mov  ah,3Fh                  ; read from file
           mov  dx,offset buffer        ;
           mov  cx,max_f_size           ;
           int  21h                     ;
           jc   short dev_names_d       ;
           mov  ah,3Eh                  ; close the file
           int  21h                     ;

           mov  si,offset buffer        ;
dev_names_l:                            ;
           mov  al,[si]                 ;
           or   al,al                   ; if null found, then end of file
           je   short dev_names_d       ;
           cmp  al,\'V\'                  ;
           je   short dev_names_v       ;
dev_names_n:
           add  si,dn_line_s            ; length of each line
           jmp  short dev_names_l       ;
dev_names_v:
           mov  ax,[si+1]               ; get vendor id number
           cmp  ax,VendorID             ;
           jne  short dev_names_n       ;
           mov  di,(Vendor_N+3)         ;
           add  si,03                   ;
dev_n_v_l: lodsb                        ;
           stosb                        ;
           or   al,al                   ;
           jnz  short dev_n_v_l         ;

dev_names_l1:
           mov  al,[si]                 ;
           or   al,al                   ; if null found, then end of file
           je   short dev_names_d       ;
           cmp  al,\'V\'                  ; if \'V\' found then no more devices
           je   short dev_names_d       ;   for this vendor
           cmp  al,\'D\'                  ;
           je   short dev_names_e       ;
dev_names_n1:                           ;
           add  si,dn_line_s            ; length of each line
           jmp  short dev_names_l1      ;
dev_names_e:
           mov  ax,[si+1]               ; get device id number
           cmp  ax,DeviceID             ;
           jne  short dev_names_n1      ;
           mov  di,(Device_N+3)         ;
           add  si,03                   ;
dev_n_v_l1:                             ;
           lodsb                        ;
           stosb                        ;
           or   al,al                   ;
           jnz  short dev_n_v_l1        ;
dev_names_d:
           ret
dev_names  endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; delay -- Delay in milliseconds
; on entry:
;  ax = delay time in milliseconds
; on exit:
;  nothing
delay      proc near uses ax cx dx
           mov  dx,1000                 ; multiply by 1000 (convert to micro)
           mul  dx                      ; dx:ax = time in microseconds
           xchg ax,dx                   ; cx:dx = time
           xchg ax,cx                   ;
           mov  ah,86h                  ; BIOS delay service
           int  15h                     ;
           ret                          ;
delay      endp                         ;

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Prtstring  proc near uses ax bx dx si
           mov  ah,06                   ; DOS print char service
Ps1:       lodsb                        ; Get character & point to next one
           or   al,al                   ; End of string?
           jz   short ps2               ; Yes, so exit
           mov  dl,al                   ;
           int  21h                     ; Output a character
           jmp  short Ps1               ; Keep doing it
Ps2:       ret
Prtstring  endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
PrtHex     proc near uses ax
           xchg ah,al
           call prthexn
           xchg ah,al
           call prthexn
           ret
PrtHex     endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
PrtHexN    proc near uses ax bx cx dx
           mov  cx,02
PLoopN:    rol  al,04          ;
           push ax             ;
           and  al,0Fh         ;
           daa                 ;
           add  al,0F0h        ;
           adc  al,40h         ;
           mov  ah,02          ;
           mov  dl,al          ;
           int  21h            ;
           pop  ax             ;
           loop PLoopN         ;
           ret
PrtHexN    endp

;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
PrtDec     proc near uses ax cx dx di
           mov  cx,0FFFFh               ; Ending flag
           push cx
           mov  cx,10
PD1:       xor  dx,dx
           div  cx                      ; Divide by 10
           add  dl,30h                  ; Convert to ASCII
           push dx                      ; Store remainder
           or   ax,ax                   ; Are we done?
           jnz  short PD1               ; No, so continue
PD2:       pop  dx                      ; Character is now in DL
           cmp  dx,0FFFFh               ; Is it the ending flag?
           je   short PD3               ; Yes, so continue
           mov  ah,02                   ;
           int  21h                     ;
           jmp  short PD2               ; Keep doing it
PD3:       ret
PrtDec     endp



;\';\';\';\';
get_dev_id proc near uses alld ds es

           push cs
           push cs
           pop  ds
           pop  es

;;;;;;;;; clear out our buffer
           mov  di,offset buffer
           mov  cx,800h
           mov  al,20h
           rep
           stosb
;;;;;;;;;;


           xor  eax,eax
           xor  edx,edx
           mov  ax,ds
           shl  eax,4
           mov  dx,offset get_dev_dis
           add  eax,edx
           mov  si,offset stand_req_id
           mov  [si+14],eax

           xor  eax,eax
           xor  edx,edx
           mov  ax,ds
           shl  eax,4
           mov  dx,offset buffer
           add  eax,edx
           mov  si,offset stand_req_id
           mov  [si+14],eax

           mov  dx,IOAddr
           add  dx,08h
           in   eax,dx
           shr  eax,4
           mov  es,ax
           xor  di,di

           xor  eax,eax
           xor  edx,edx
           mov  ax,ds
           shl  eax,4
           mov  dx,offset stand_req_id
           add  eax,edx
           mov  es:[di],eax

           xor  eax,eax
           xor  edx,edx
           mov  ax,ds
           shl  eax,4
           mov  dx,offset buffer
           add  eax,edx
           mov  es:[di+4],eax

;\';\';\';\';\';

           mov  ah,3Ch
           mov  cx,20h
           mov  dx,offset tempfile
           int  21h
           mov  bx,ax
           mov  ah,40h
           mov  dx,offset buffer
           mov  cx,800h
           int  21h
           mov  ah,3Eh
           int  21h

           ret
get_dev_id endp

tempfile  db \'temp.bin\',0

.para      ; align on a 16-byte boundary

;                33222222  22221111  11111100  00000000
;                10987654  32109876  54321098  76543210
stand_req_id db  00000000b,00000000b,00000000b,00000001b
             db  00001001b,10000000b,00000000b,00000000b
             db  00000000b,11100000b,00000001b,00101101b
             dw  00h,00h

get_dev_dis  db  80h         ; [bmRequest type] device->host, standard, device
             db  06h         ; [bRequest]       GET_DESCRIPTOR
             dw  01h         ; [wValue]         device
             dw  00h         ; [wIndex]         zero
             dw  08h         ; [wLength]        8 bytes

.para      ; align on a 16-byte boundary

;                33222222  22221111  11111100  00000000
;                10987654  32109876  54321098  76543210
stand_req_in db  00000000b,00000000b,00000000b,00000001b
             db  00001001b,10000000b,00000111b,11111111b
             db  11111111b,11101000b,00000001b,01101001b
             dw  00h,00h

;\';\';\';\';\'



;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
v86_mode_s   db  13,10,\'Can not run in V86 mode.  Must be real mode DOS\',0
DetectS      db  13,10,\'Detecting PCI BIOS ... \',0
PCIBoisFS    db  \' found.  v\',0
PCIBoisNS    db  \' NOT found!\',0
FoundUSBTS   db  13,10,10,\'Found USB Controller:  \',0
VendorIDS    db  13,10,\'           Vendor ID:  \',0
DeviceIDS    db  13,10,\'           Device ID:  \',0
BusNumberS   db  13,10,\'  Bus #/Dev #/Func #:  \',0
CommandRS    db  13,10,\'    Command Register:  \',0
StatusRS     db  13,10,\'     Status Register:  \',0
RevisionS    db  13,10,\'       Revision Code:  \',0
ClassCodeS   db  13,10,\' Class/Sub/Interface:  \',0
BusLatS      db  13,10,\'         Bus Latency:  \',0
HeaderS      db  13,10,\'         Header Type:  \',0
CacheS       db  13,10,\'     Cache Line Size:  \',0
SelfTestS    db  13,10,\'      Self Test Byte:  \',0
IOPortsS     db  13,10,\'       Address Space:  \',0
IRQNumS      db  13,10,\'          IRQ Number:  \',0
IntNumS      db  13,10,\'          INT Number:  \',0
status_str   db  13,10,\'     Status Register:  \',0
cmmnd_str    db  13,10,\'    Command Register:  \',0
frame_str    db  13,10,\'      Frame Register:  \',0
frameb_str   db  13,10,\' Frame Base Register:  \',0
port0_str    db  13,10,\'     Root Hub port 1: (\',0
port1_str    db  13,10,\'     Root Hub port 2: (\',0
port_dis_s   db  \') Port disabled\',0
port_susp_s  db  \') Port suspened\',0
port_enbl_s  db  \') Port enabled:\',0
port_dev_p   db  \' A device is present at \',0
port_dev_np  db  \' No device present.\',0
port_low_s   db  \'low speed\',0
port_full_s  db  \'full speed\',0

enable_s     db  13,10,10,\'Enabling PCI bus...\',0
e_bad_s      db  \'Error!\',0
e_good_s     db  \'Successful.\',0

no_memory_s  db  13,10,\'Out of memory\',0

VendorID     dw  00h ; Vendor ID number
DeviceID     dw  00h ; Device ID number
Vendor_N     db  \' - \'
             dup dn_line_s,0
Device_N     db  \' - \'
             dup dn_line_s,0
devfile      db  \'devnums.bin\',0

IOAddr       dw  ?        ; Address space of port  (32 bytes)
fram_l_ptr   dup 4,0      ; physical dword pointer to 1024 byte frame
fram_l_bse   dw  ?        ; segment to 8192 byte frame base

dev_index    dw  00h
bus_num      db  00h
dev_func     db  00h

buffer       dup 32768,?    ; multi-use buffer

.end
; =-=-=-=-=-=-=-=-=- CUT HERE -=-=-=-=-=-=-=-=-=



; =-=-=-=-=-=-=-=-=- CUT HERE -=-=-=-=-=-=-=-=-=
; usb.inc

; =-=-=-=-=- boolean
true        equ  1
false       equ  0

; =-=-=-=-=- max size of \'devnums.bin\'
max_f_size  equ  16384      ; max size of \'devnums.bin\' file

; =-=-=-=-=- Size of each line in \'devnums.bin\'
dn_line_s   equ  48         ; 48 bytes per line

.end
; =-=-=-=-=-=-=-=-=- CUT HERE -=-=-=-=-=-=-=-=-=



All rights reserved
Legal Notice
Copyright ? 1984-2003 Forever Young Software
Return to My Home Page
else
驱动小牛
驱动小牛
  • 注册日期2002-10-21
  • 最后登录2004-06-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-04-26 13:14
http://www.cybertrails.com/~fys/usb.htm
游客

返回顶部