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

📄 md.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 5 页
字号:
        ret

ResetSerialMouse2       ENDP

;*****************************************************************************
;
; ResetSerialMouse
;
; This procedure will reset a serial mouse on the given COM port and will
; return an indication of whether a mouse responded or not.
;
; The function now also checks for the presence of a 'B' as well as an 
; 'M' to determine the presence of a pointing device.  Also, if the 'M' is 
; followed by a '3' the serial mouse is a Logitech.
;
; Mouse     returns M
; Ballpoint returns B
;
; ENTRY   DX    Base I/O address of COM port to use
;         CX    Number of msecs to use for delays
;
; EXIT    AX    Mouse Type
;
;*****************************************************************************
ResetSerialMouse PROC NEAR

      push      dx                  ; Save environment.
      push      si
      push      di
      push      es

      address   IER RXB             ; Get address of Interrupt Enable Reg.       
      DelayIn   al,dx               ; Get current contents of IER and       
      push      ax                  ; save them.       
      push      dx                  ; Save address of IER.       
      xor       al,al               ; Disable all interrupts at the       
      DelayOut  dx,al               ; COM port level.       

      address   MCR IER             ; Get address of Modem Control Reg.       
      mov       al,MC_DTR           ; Set DTR active; RTS, OUT1, and OUT2       
      DelayOut  dx,al               ; inactive. This powers down mouse.       

      push      cx                  ; Save amount of time to delay.       
      call      SetupForWait        ; Set up BX:CX and ES:DI properly for       
      assume    es:nothing          ; upcoming delay loop.       

      address   RXB MCR             ; Get address of Receive Buffer.       
;
; Now, we wait the specified amount of time, throwing away any stray
; data that we receive. This gives the mouse time to properly reset
; itself.
;
rsm_waitloop:
      DelayIn   al,dx               ; Read and ignore any stray data.
      call      IsWaitOver          ; Determine if we've delayed enough.
      jnc       rsm_waitloop        ; If not, keep waiting.

; Wait is over.

      address   LSR RXB             ; Get address of Line Status Reg.
      DelayIn   al,dx               ; Read it to clear any errors.
      address   MCR LSR             ; Get address of Modem COntrol Reg.
      mov       al,MC_DTR+MC_RTS+MC_OUT2 ; Set DTR, RTS, and OUT2 active
                                         ; OUT1 inactive.
      DelayOut  dx,al               ; This powers up the mouse.

      pop       cx                  ; Get amount of time to delay.
      call      SetupForWait        ; Set up BX:CX and ES:DI properly for
      assume    es:nothing          ; the upcoming delay loop.
;
; We give the mouse the specified amount of time to respond by sending
; us an M. If it doesn't, or we get more than 5 characters that aren't
; an M, we return a failure indication.
;

      address   LSR MCR             ; Get address of Line Status Reg.
      mov       si,5                ; Read up to 5 chars from port.
      mov       bl,'3'              ; '3' will follow 'M' on Logitech.
      mov       bh,'B'              ; 'B' for BALLPOINT
      mov       ah,'M'              ; Get an M. (We avoid doing a cmp al,M
                                    ; because the M could be left floating
                                    ; due to capacitance.)
rsm_getchar:
      DelayIn   al,dx               ; Get current status.
      test      al,LS_DR            ; Is there a character in Receive Buff?
      jnz       rsm_gotchar         ; Yes! Go and read it.
      call      IsWaitOver          ; No, determine if we've timed out.
      jnc       rsm_getchar         ; Haven't timed out; keep looking.

      mov       bx,NO_MOUSE
      jmp short rsm_leave           ; Timed out. Leave with NO_MOUSE.

rsm_gotchar:
      address   RXB LSR             ; Get address of Receive Buffer.
      DelayIn   al,dx               ; Get character that was sent to us.
      cmp       al,ah               ; Is it an M?
      jne       check_for_b
;
; We received an 'M', now wait for next character to see if it is a '3'.
;
      mov       cx,1                ; Wait between 55.5 and 111ms for
      call      SetupForWait        ;   next character.
      address   LSR RXB             

rsm_waitfor3:
      DelayIn   al,dx               ; Get current status.
      test      al,LS_DR            ; Is there a character in Receive Buff?
      jnz       rsm_gotchar3        ; Yes! Go and read it.
      call      IsWaitOver          ; No, determine if we've timed out.
      jnc       rsm_waitfor3        ; Haven't timed out; keep looking.

; Not a Logitech - must be a standard Microsoft compatible serial mouse.

      jmp short rsm_notLT

rsm_gotchar3:
      address   RXB LSR             ; Get address of Receive Buffer.
      DelayIn   al,dx               ; Get character that was sent to us.
      cmp       al,bl               ; Is it a 3?
      jne       rsm_notLT

      mov       bx,LT_MOUSE         ; Yes, we've found a Logitech M+ series,
      address   LSR RXB             ; Choose Line Status Register.
      jmp short rsm_leave           ;   3 button mouse

rsm_notLT:
      mov       bx,SERIAL_MOUSE     ; We didn't get the '3' after the 'M'
      address   LSR RXB             ; Choose Line Status Register.
      jmp short rsm_leave           ; We still have a standard serial mouse.

check_for_b:
      cmp       al,bh               ; Is it a B?
      jne       rsm_next_char

      mov       bx,MSBPOINT_MOUSE   ; We've found a BallPoint Mouse
      address   LSR RXB             ; Choose Line Status Register.
      jmp short rsm_leave

rsm_next_char:
      address   LSR RXB             ; Oh well. Get address of LSR again.
      dec       si                  ; Have we read 5 chars yet?
      jnz       rsm_getchar         ; Nope, we'll give him another try.

; We've read many characters - No a single 'M' or 'B' in the lot.

      mov       bx,NO_MOUSE

rsm_leave:
      pushf                         ; Save flags


; Clear out any extra incoming characters

      mov       cx,2                ; Get amount of time to delay.
      call      SetupForWait        ; Set up BX:CX and ES:DI properly for
      assume    es:nothing          ; the upcoming delay loop.

rsm_ClearAll:
      DelayIn   al,dx               ; Read the LSR to clear any errors.
      address   RXB LSR             ; Get address of Receive Buffer.
      DelayIn   al,dx               ; Read and ignore any stray data.
      address   LSR RXB             ; Get address of Line Status Register.

rsm_ClearPort:
      call      IsWaitOver          ; Determine if we've timed out.
      jnc       rsm_ClearAll        ; Haven't timed out; keep looking.


      popf                          ; Restore flags

      pop       dx                  ; Get address of IER.
      pop       ax                  ; Get old value of IER.
      DelayOut  dx,al               ; Restore IER.

      pop       es                  ; Restore environment.
      assume    es:nothing
      pop       di
      pop       si
      pop       dx
      mov       ax,bx               ; Set return value.
      ret

ResetSerialMouse        ENDP

;*****************************************************************************
;
;       SetupForWait
;
;       This procedure accepts the number of milliseconds that we will want
;       to delay for and will set things up for the wait.
;
;       ENTRY   CX              Number of Clock ticks to wait for.
;
;       EXIT    None.
;
;       ALTERS  CX
;
;       CALLS   none
;


SetupForWait    PROC    NEAR

        push    ax                        ; Do your saving !
        push    es

        xor     ax,ax
        mov     es,ax                     ; Point to 40:6C = 0:46C
        mov     ax,es:[LW_ClockTickCount] ; Get tick count in AX.
        add     ax,cx                     ; [Current + delay] = delay ends.
        mov     ds:[SemaphoreWord],ax     ; Save ending time in Semiphore

        pop     es                        ; Restore now !
        pop     ax
        
        ret

SetupForWait    ENDP

;*****************************************************************************
;
;       IsWaitOver
;
;       This procedure accepts the current time and the ending time and
;       return and indication of whether the current time is past
;       the ending time.
;
;       ENTRY  None
;
;       EXIT    carry clear     Current time is not past ending time
;               carry set       Current time is past ending time
;
;       ALTERS  none
;
;       CALLS   none
;

IsWaitOver      PROC    NEAR

        push    ax                         ; Preserve AX
        push    es                         ; Preserve ES
        push    bx
        sti                                ; Hosebag BIOS bugs can't get me.
        xor     ax,ax
        mov     es,ax                      ; Point to 40:6C = 0:46C
        mov     ax,es:[LW_ClockTickCount]  ; Get tick count in AX.
        sti
        mov     bx,ds:[SemaphoreWord]
        cmp     bx,ax                      ; This will set carry accordingly.

        pop     bx
        pop     es                         ; Restore ES
        pop     ax                         ; Restore AX
        ret

IsWaitOver      ENDP

;*****************************************************************************
;
; LookForPS2Mouse
;
;*****************************************************************************
LookForPS2Mouse  PROC  NEAR
;
; Lets make the Int 15h, C201h BIOS call to reset the pointing device.
; If the call is supported, and returns success then we know that we have
; a PS/2 mouse.
;
      stc
      mov       bx,0ffffh           ; Initialize, see later if it changes.
      mov       ax,0c201h
      int       15h                 ; Reset Pointing device.
      jc        No_PS2_Mouse        ; Function call unsuccesful.

      cmp       bh,0ffh             ; BH should be device ID, it should not
      je        No_PS2_Mouse        ;   be what we initialized it to (FF).
;
; The following sequence of Int 15h calls will determine if a Logitech
; PS/2 mouse is present.  This information was obtained from Logitech.
;
      mov       ax,0C203h           ; Set resolution to 1 cnt/mm
      mov       bh,0h
      int       15h
      jc        PS2_Mouse             

      mov       ax,0C206h           ; Set scaling to 1:1
      mov       bh,1h
      int       15h
      jc        PS2_Mouse             

      mov       ax,0C206h           ; Set scaling to 1:1
      mov       bh,1h
      int       15h
      jc        PS2_Mouse             

      mov       ax,0C206h           ; Set scaling to 1:1
      mov       bh,1h
      int       15h
      jc        PS2_Mouse             

      mov       ax,0C206h           ; Get status
      mov       bh,0h
      int       15h
      jc        PS2_Mouse             

      or        cl,cl               ; Is resolution 1 cnt/mm?
      jz        PS2_Mouse           ; Yes, then not a Logitech.
;
; If cl is not zero (i.e. 1 cnt/mm) then it is the number of buttons
; and we've found a Logitech 3-button PS/2 mouse
;
LT_PS2_Mouse:
      mov       ax,LT_PS2MOUSE
      jmp short PS2MouseFound

PS2_Mouse:
      mov       ax,MSPS2_MOUSE
      jmp short PS2MouseFound

No_PS2_Mouse:
      mov       ax,NO_MOUSE

PS2MouseFound:
      ret

LookForPS2Mouse  ENDP


;*****************************************************************************
;
;       TestForPS2
;
;       This procedure will attempt to find a PS/2 mouse in the system and
;               return the results of this search.
;
;       ENTRY   fSingle8259     Non-zero if we have a single 8259A
;
;       EXIT    Carry clear     A PS/2 style Microsoft mouse was found
;               Mouse interrupts disabled at 8042.
;               Mouse disabled at 8042.
;               Mouse is reset.
;
;               Carry set       A PS/2 style Microsoft mouse was not found
;
;       ALTERS  AX, CX
;
;       CALLS   CheckForAuxSupport, MouseIntOff, CheckForMSMouse
;


TestForPS2      PROC    NEAR

        call    CheckForLogitechPS2     ; Check for Logitech PS/2 Mouse.
;       jmp     tfp_leave
        jc      tfp_CheckForMS          ; Check for MS/IBM mouse if not.

⌨️ 快捷键说明

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