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

📄 prnusb.asm

📁 DOS下的USB驱动源码,包括UHCI
💻 ASM
📖 第 1 页 / 共 2 页
字号:
mov cs:urb.nr_of_packets,0
mov cs:urb.int_interval,0
mov cs:urb.error_count,0
mov cs:urb.timeout,0
mov cs:urb.next_urb_off,0
mov cs:urb.next_urb_seg,0

;now call DosUHCI
push cs
pop ds
mov dx,offset cs:urb
int 65h

;read successful?
inc cs:retry_count        ;always inc error counter
cmp cs:retry_count,5      ;already four retries?
jae get_status_err
cmp cs:urb.status,0       ;transaction OK?
je  get_status_ok ;yes
cmp cs:urb.status,88h      ;NAK?
jne get_status_err ;no, different error - exit without retry
jmp repeat_get_status     ;got NAK, retry

get_status_ok:
mov al,byte ptr temp_buffer[0]
mov cs:prtstatus,al

if showflag
mov cl,31 ;"O"
call show
mov cl,al
call show
endif

xor ax,ax ;clear

test cs:prtstatus,00100000b ;paper empty bit
jz test_for_select ;jmp if bit in prtstatus NOT set
mov ax,8009h  ;paper empty
jmp prtstatus_check_done

test_for_select:
test cs:prtstatus,00010000b ;selected bit set = no error
jnz test_for_error ;jmp if bit in prtstatus IS set
mov ax,8002h  ;device not ready
jmp prtstatus_check_done

test_for_error:
test cs:prtstatus,00001000b ;is that bit set = no error! ?
jnz prtstatus_check_done ;jmp if bit in prtstatus IS set
mov ax,800Ah  ;write error

prtstatus_check_done:
clc
mov cs:retry_count,0
pop bx
pop es
ret

get_status_err:
xor ax,ax ;clear
stc
mov cs:retry_count,0
pop bx
pop es
ret

readstatus endp

;**********************************************************
do_check proc near
        ;check if interrupt 65h is set or uninitalized
        ;return dx=1 if installed
        xor dx,dx ;zero = default
        xor ax,ax
        mov es,ax ;set to zero
        mov bx,es:194h ;read offset into bx
        mov ax,es:196h ;read segment
        mov es,ax      ;segment in es
        mov     ax,es  ;test if 0:0 vector -> no driver
        or      ax,bx
        jz      not_loaded
        mov     ax,es:[bx]
        cmp     al,0CFh ;IRET?
        je      not_loaded
        mov dx,1 ;installed
not_loaded:

ret
do_check endp
;***************************************************************************
read_commandline proc near
;determine length of command line first
        ;rh0_bpb_tbo     dw      ?       ;offset address of pointer
        ;rh0_bpb_tbs     dw      ?       ;segment address of pointer 
        cld
        push es
        mov di,es:[bx].rh0_bpb_tbo  ;position of command_string
        mov cx,es:[bx].rh0_bpb_tbs  ;segment
        mov es,cx
        mov al,0Dh  ;CR
        xor cx,cx
        mov cl,80   ;read 80 max
 repne  scasb
        pop es
        mov dx,di
        sub dx,es:[bx].rh0_bpb_tbo
        ;check if valid length read
        cmp dx,0
        ja chl0
        jmp read_commandline_done
chl0:
        cmp dx,80
        jb chl1
        jmp read_commandline_done
chl1:
        cld
        push es
        mov di,es:[bx].rh0_bpb_tbo  ;position of command_string
        mov cx,es:[bx].rh0_bpb_tbs  ;segment
        mov es,cx
        mov al,'/' 
        xor cx,cx
        mov cl,dl ;length in dx
 repne  scasb
        cmp cx,0 ;not found?
        jne nc0f ;jmp if found
        pop es   ;therefore no jcxz
        jmp nextcommand1  ;not found
nc0f:
        mov ax,es:[di] ;now read that byte
        cmp al,45h ;E?
        jne nc0a
        mov ax,es:[di+1] ;read endpoint number
        sub ax,30h ;just one number max 9
        mov cs:endpointnr,al
        jmp nc0b
nc0a:
        cmp al,44h ;D?
        jne nc0b
        mov ax,es:[di+1] ;read device number
        sub ax,30h ;just one number max 9
        mov cs:devicenr,al
nc0b:
        pop es
        ;now test for next command
nextcommand1:
        cld
        push es
        ;leave di and continue there
        ;mov di,es:[bx].rh0_bpb_tbo  ;position of command_string
        mov cx,es:[bx].rh0_bpb_tbs  ;segment
        mov es,cx
        mov al,'/' 
        xor cx,cx
        mov cl,dl ;length 
 repne  scasb
        cmp cx,0 ;not found?
        jne nc1f ;jmp if found
        pop es   ;therefore no jcxz
        jmp nextcommand2  ;not found
nc1f:
        mov ax,es:[di] ;now read that byte
        cmp al,45h ;E?
        jne nc1a
        mov ax,es:[di+1] ;read endpoint number
        sub ax,30h ;just one number max 9
        mov cs:endpointnr,al
        jmp nc1b
nc1a:
        cmp al,44h ;D?
        jne nc1b
        mov ax,es:[di+1] ;read device number
        sub ax,30h ;just one number max 9
        mov cs:devicenr,al
nc1b:
        pop es
        ;now test for next command
nextcommand2:

;check if values read ok
cmp devicenr,0
ja dnext1      ;ok
mov devicenr,1 ;default
dnext1:
cmp devicenr,10
jb dnext2      ;ok
mov devicenr,1 ;default
dnext2:
cmp endpointnr,0
ja enext1        ;ok
mov endpointnr,2 ;default
enext1:
cmp endpointnr,10
jb enext2        ;ok
mov endpointnr,2 ;default
enext2:
read_commandline_done:

ret
read_commandline endp

;******************************************************
show proc near ;show number in cl
	      ;pusha                 ; Register sichern
	      push  di
	      push  ax
	      push  es
	      push  cx
	      push  ax

	      push  0B800h          ; Video-Segment
	      pop   es              ; ES auf Video-RAM
	      mov   di, 450         ; StartOffset
	      xor   ch,ch           ; clear high byte
	      inc showptr
	      inc showptr
	      mov ax,showptr
	      add di,ax

	      cld
	      mov   ax, es:[di]     ; Farbe ermitteln
	      mov   al,cl           ; write number to show
	      add   al,48           ; convert to ascii
	      stosw                 ; write to es:di

	      pop   ax
	      pop   cx
	      pop   es
	      pop   ax
	      pop   di
	      ;popa
ret
show endp

;****************************************************************
;*      DOS COMMAND PROCESSING                                  *
;****************************************************************

;command 0      Initialization  *********************************
Initialization:
        call    read_commandline
        call    initial                 ;display message
        lea     ax,initial              ;set Break Addr. at initial
        mov     es:[bx].rh0_brk_ofs,ax  ;store offset address
        mov     es:[bx].rh0_brk_seg,cs  ;store segment address
        jmp     done                    ;set done status and exit


;command 8      Output  *****************************************
Output:

	mov	cx,es:[bx].rh8_count	;load output count
        jcxz    out_done                ;no bytes to print - leave

        push    cs
        pop     ds   ;set ds to cs

;check if usb driver installed
        push es
        push bx
        call    do_check
        pop bx
        pop es
        cmp dx,1 ;    urb.transaction_token,47h
        je check_ok
        mov     ax,800Ah                ;write error
        mov     cx,0 ;cs:bytes_done
        mov     es:[bx].rh8_count,cx    ;return output count 
	jmp	load_status		;load status & exit

check_ok:

        push es
        push bx
        call readstatus ;find out if printer reports an error first
        pop bx
        pop es
        cmp ax,0
        je out_continue
        ;ax is filled with error return code for DOS

        if showflag
        push es
        push bx
        mov cl,17 ;"A"
        call show
        mov cl,al
        call show
        pop bx
        pop es
        endif

        mov     es:[bx].rh8_count,0     ;return output count 0
        jmp	load_status		;load status & exit

out_continue:
        push    cs
        pop     ds   ;set ds to cs
        push es
        push bx
        call do_out ;now seg/off/bytes read from header in do_out proc
        pop bx
        pop es
        cmp cs:urb.status,0 ;ok?
        je out_done
        ;now return error
        ;ax is filled with error return code for DOS

        if showflag
        push es
        push bx
        mov cl,16 ;"@"
        call show
        mov cl,cs:urb.status
        call show
        pop bx
        pop es
        endif

        mov     cx,cs:bytes_done        ;have to return these
        mov     es:[bx].rh8_count,cx    ;return output count
        jmp	load_status		;load status & exit

out_done:  
        mov     ax,0                    ;no error
	jmp	load_status		;load status & exit

;****************************************************************
;*      ERROR EXIT                                              *
;****************************************************************

isunknown: 
	or	es:[bx].rh_status,8003h	;set error bit and error code
	jmp	done			;set done and exit

;****************************************************************
;*      COMMON EXIT                                             *
;****************************************************************
load_status:
	mov	cx,cs:rh_seg		;restore request header 
	mov	es,cx			; segment to es
	mov	cx,cs:rh_ofs		;restore offset also
	xchg	bx,cx			;switch them
        mov     es:[bx].rh_status,ax    ;return status, ax filled above
        ;mov     es:[bx].rh8_count,cx    ;return output count - leave it
	jmp	done			;set done bit and exit

done:   or      es:[bx].rh_status,0100h ;set done bit

	pop	si			;restore all registers
	pop	di
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	pop	es
	pop	ds
        popf
	ret				;return to DOS

;****************************************************************
;*      END OF PROGRAM                                          *
;****************************************************************

;this procedure is called from the Initialization command and
;is executed only once. We tell DOS that the next available
;memory location (Break Address) is here. This allows DOS to over
;write this code; we save space.

initial	proc	near	;display message on console
	lea	dx,msg1	;message to be displayed
	mov	ah,9	;display
	int	21h	;DOS call

        mov  ah,02          ;
        mov  dl,devicenr    ;
        add  dl,48          ;convert to ascii
        int  21h            ;

        lea     dx,msg2 ;message to be displayed
	mov	ah,9	;display
	int	21h	;DOS call

        mov  ah,02          ;
        mov  dl,endpointnr  ;
        add  dl,48          ;convert to ascii
        int  21h            ;

        lea     dx,crlf ;message to be displayed
	mov	ah,9	;display
	int	21h	;DOS call

	ret		;return to caller
initial	endp

msg1    db      0dh,0ah,"Printer device driver for DosUSB, Version 1.2",0dh,0ah
;        db      "Not supporting GDI or Windows printers!",0dh,0ah
        db      "Device number: $"
msg2    db      " Endpoint number: $"
crlf    db      0dh,0ah,"(can be set with /DX and /EX)",0dh,0ah,0ah,"$"

printer	endp		;end of printer procedure
cseg	ends		;end of cseg segment
	end	begin	;end of program

⌨️ 快捷键说明

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