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

📄 md.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;       Interrupts have to be disabled from the time we find the buffers
;       empty and write the command byte until the time that the data that
;       the command produces is read. Therefore, we will disable and enable
;       interrupts each time through the loop to ensure that interrupts will
;       not be disabled for too long a time.
;

wcr_loop:
        cli                             ; Disable ints before reading status.
        in      al,STATUS_8042          ; Get 8042's current status.
        test    al,I_FULL + O_FULL      ; Are input and output buffers empty?
        jz      wcr_success             ; Yes! Go write the command byte.
        sti                             ; Nope. Reenable ints and keep trying
        loop    wcr_loop                ; the desired number of times.
        dec     ah
        jnz     wcr_loop

;
; Interrupts are enabled.
;

        pop     ax                      ; Restore registers.
        pop     cx

        stc                             ; Show that we failed.
        ret

;
; Interrupts are disabled and carry is clear (from TEST instruction).
;

wcr_success:
        pop     ax                      ; Get saved command byte.
        out     CONTROL_8042,al         ; Write command byte out.
        pop     cx                      ; Restore register.
        ret                             ; Carry is already clear.

WriteControlRegister    ENDP

;*****************************************************************************
;
;       MouseIntOff
;
;       This procedure will disable the mouse and mouse interrupts at the 8042
;               level.
;
;       Note that it assumes that the keyboard is enabled upon entry to this
;               procedure.
;
;       ENTRY   none
;
;       EXIT    Carry clear     Mouse and mouse interrupts are disabled.
;
;               Carry set       Some error occurred.
;
;       ALTERS  AL
;
;       CALLS   WriteControlRegister, Read8042CommandByte, Write8042CommandByte
;


MouseIntOff     PROC    NEAR

        mov     al,CMD8042_DISABLE_AUX  ; Disable the aux device.
        call    WriteControlRegister
        jc      mioff_leave             ; Leave if error.
        mov     al,CMD8042_DISABLE_KBD  ; Disable the keyboard.
        call    WriteControlRegister
        jc      mioff_leave             ; Leave if error.
                                        ; INTERRUPTS DISABLED!!

        call    Read8042CommandByte     ; Get the current command byte.
                                        ; INTERRUPTS ENABLED!!
        jc      mioff_cleanup           ; Leave if error.
        and     al,not AUX_INT_ENABLE   ; Disable mouse interrupts.
        call    Write8042CommandByte    ; Write out altered command byte.

mioff_cleanup:
        pushf                           ; Save return status.

mioff_reenable_kbd:
        mov     al,CMD8042_ENABLE_KBD   ; Reenable the keyboard.
        call    WriteControlRegister    ; If an error occurs, keep trying to
        jc      mioff_reenable_kbd      ; reenable it.
                                        ; INTERRUPTS DISABLED!!
        popf                            ; Restore return status.
                                        ; INTERRUPTS ENABLED!!

mioff_leave:                            ; Carry set/clear appropriately.
        ret

MouseIntOff     ENDP

;*****************************************************************************
;
;      CheckForMSMouse
;
;      This procedure checks to see if a Microsoft mouse or IBM mouse 
;      is attached to the auxiliary interface of the 8042.
;
;      ENTRY      Mouse interrupts disabled.
;
;      EXIT      Carry clear      A PS/2 style mouse was found
;            AX            MS, IBM , Logitech
;            Mouse interface disabled.
;            Mouse is reset.
;
;            Carry set      PS/2 mouse was not found
;
;      ALTERS      AX, CX
;
;      CALLS      SendToMouse, SendToMouseAndTestData, GetMouseData
;            WriteControlRegister, ResetPS2Mouse
;


CheckForMSMouse      PROC      NEAR

      mov      al,CMD8042_ENABLE_AUX      ; Make sure aux interface is enabled
      call      WriteControlRegister      ; so we can talk to the mouse.
      jc      cfmm_leave            ; Leave if we can't enable it.

      mov      cx,5                  ; Only 5 tries at this!

cfmm_retry:
      call      ResetPS2Mouse            ; Try to reset the mouse.
      jc      cfmm_failure            ; Try again if we failed.
      
;      call    CheckForLogitechPS2     ; Check for Logitech PS/2 Mouse.
;      jc      noLogiTech                   ; Logitech mouse not found
;      mov     ax,LT_PS2MOUSE
;      jmp     short cfmm_cleanup      ; mouse type determined

;
; The following sequence of commands checks to see if the mouse that we
;      just succeeded in resetting is a Microsoft mouse. 
;
; Note that we have to check to determine if the mouse responds with either
;      MCMD_ACK or with what was sent because of the differences between
;      the 200ppi and 400ppi PS/2 style mouse. The 200ppi mouse responds
;      with MCMD_ACKs, while the 400ppi mouse responds with whatever was
;      sent to it.
;
noLogiTech:
      mov      al,MCMD_ECHO            ; Send Select Echo Command.
      call      SendToMouse
      jc      cfmm_failure            ; Try again if we failed.

      mov      ax,'GG'                  ; Next "command" in signature.
      call      SendToMouseAndTestData
      jc      cfmm_failure            ; Try again if we failed.

      mov      ax,'DD'                  ; Next "command" in signature.
      call      SendToMouseAndTestData
      jc      cfmm_failure            ; Try again if we failed.

      mov      ax,'GG'                  ; Next "command" in signature.
      call      SendToMouseAndTestData
      jc      cfmm_failure            ; Try again if we failed.

      mov      al,MCMD_KILL_ECHO      ; Leave Echo mode.
      call      SendToMouse
      jnc      cfmm_signature_sent      ; If successful, have sent signature.

cfmm_failure:
      loop      cfmm_retry            ; Try again.
;
; at this point there is no mouse on AUX port at all
;

       stc                              ; carry set for no mouse at all.
       jmp      short cfmm_cleanup

;
; At this point, we have sent the signature string to the mouse.
;      If we have a Microsoft mouse out there, it will respond to a
;      Microsoft extended command.  If there is no response we have an
;      IBM mouse.
;
; Note that we have to test to see if the mouse responds with either a
;      MCMD_ACK or a MCMD_RESEND. This is because a 200ppi mouse responds
;      with MCMD_ACK, while a 400ppi mouse responds with MCMD_RESEND.
;

cfmm_signature_sent:
      mov      ax,(MCMD_RESEND SHL 8) + MCMD_MS_VERS ; Set command and return.
      call      SendToMouseAndTestData
      jc      cfmm_cleanup            ; Leave if unable to send command.

; IBM Mouse fails on this call because it will not send data in
; response to the above Microsoft version command

        call      GetMouseData            ; Read current version number.
      jc      noVerNumber            ; must have IBM mouse
        mov     ax,MSPS2_MOUSE          ; return MS PS2 Mouse.
      jmp      short cfmm_cleanup      ; mouse type determined

noVerNumber:
      mov      ax,IBMPS2_MOUSE              ; ax = IBM PS/2 mouse found.
      clc                        ; clear carry to show mouse presence
;
; Disable the auxiliary interface before leaving.
;

cfmm_cleanup:
      ; carry set here means no PS/2 mouse
      pushf                        ; Save state of carry.
      push      ax                  ; Save version number.

cfmm_disable_aux:
      mov      al,CMD8042_DISABLE_AUX      ; Disable the auxiliary interface.
      call      WriteControlRegister
      jc      cfmm_disable_aux      ; Make sure aux interface is disabled.

      pop      ax                  ; Restore version number.
      popf                        ; Restore carry.

;
; We have found a Microsoft mouse.  The version number is in AL.
;

cfmm_leave:                         

        ; carry clear means mouse present, al indicates its type
      ; carry set upon return means no mouse found

      ret

CheckForMSMouse      ENDP

;*****************************************************************************
;
;       SendToMouse
;
;       This procedure sends a byte of command or data to the mouse.
;               Because it appears that the mouse always acknowledges the
;               sending of this byte, this is also tested for here.
;
;       ENTRY   AL              Byte of command/data to send
;
;       EXIT    Carry clear     Command/data byte sent, mouse sent MCMD_ACK
;               Interrupts enabled.
;
;               Carry set       Command/data byte not sent, or mouse never
;                                sent back MCMD_ACK
;               Interrupts enabled.
;
;       ALTERS  AX
;
;       CALLS   SendToMouseAndTestData
;


SendToMouse     PROC    NEAR

        mov     ah,MCMD_ACK           ; We will only check for MCMD_ACK being
                                      ; returned from mouse.

IF2
.ERRNZ  ($ - SendToMouseAndTestData)  ; Because we fall into it.
ENDIF

SendToMouse     ENDP

;*****************************************************************************
;
;       SendToMouseAndTestData
;
;       This procedure sends a byte of command or data to the mouse.
;               It will then test to ensure that the mouse either sent
;               back what the caller is expecting or MCMD_ACK.
;
;       ENTRY   AL              Byte of command/data to send
;               AH              Byte of data the mouse is to return
;
;       EXIT    Carry clear     Command/data byte sent, mouse responded
;                                correctly
;               Interrupts enabled.
;
;               Carry set       Command/data byte not sent, or mouse never
;                                responded correctly
;               Interrupts enabled.
;
;       ALTERS  AX
;
;       CALLS   WriteControlRegister, WriteInputBuffer, CheckMouseData
;


SendToMouseAndTestData  PROC    NEAR

        push    ax                      ; Save command/data byte.
        mov     al,CMD8042_WRITE_AUX    ; Tell 8042 we want to send a byte to
        call    WriteControlRegister    ; the auxiliary device.
        pop     ax                      ; Get saved command/data byte.
        jc      stmatd_leave            ; Leave if error.

                                        ; INTERRUPTS DISABLED!
        call    WriteInputBuffer        ; Send data/command to aux dev.
                                        ; INTERRUPTS ENABLED!
        jc      SendToMouseAndTestData  ; Retry if unsuccessful.

        mov     al,MCMD_ACK             ; Make sure mouse acknowledges that
                                        ; command/data byte was sent.

if2     ; Pass 2 of the assembler
.errnz  ($ - CheckMouseData)            ; Because we drop into it
endif   ; Pass 2 of the assembler

SendToMouseAndTestData  ENDP

;*****************************************************************************
;
;       CheckMouseData
;
;       This procedure checks that the next byte that the mouse sends us is
;               what we were expecting it to send.
;
;       Note that this procedure cannot be called with interrupts disabled.
;               If it is, interrupts will potentially be left off for a
;               long time.
;
;       ENTRY   AL              One possible data byte the mouse can send
;               AH              A second valid data byte the mouse can send
;               Interrupts enabled
;
;       EXIT    Carry clear     Mouse sent data we were expecting
;
;               Carry set       Mouse didn't send data, or sent something we
;                               weren't expecting.
;
;       ALTERS  none
;
;       CALLS   GetMouseData
;

CheckMouseData  PROC    NEAR

        push    bp                      ; Save BP.
        push    ax                      ; Save data bytes to test for.
        mov     bp,sp                   ; Address data bytes on stack.
        call    GetMouseData            ; Get next byte of data from mouse.
        jc      cmd_leave               ; Leave if error.
        cmp     al,ah                   ; Is it what we were expecting?
        je      cmd_leave               ; Yes! Leave with carry clear.
        cmp     al,byte ptr [bp]        ; Is it other byte we were expecting?
        je      cmd_leave               ; Yes! Leave with carry clear.
        stc                             ; Nope, show error and leave.

cmd_leave:                              ; Carry set/clear appropriately.
        pop     ax

⌨️ 快捷键说明

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