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

📄 md.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 5 页
字号:
      mov   InputBytes+3, al

      xor   si, si                  ; Clear the loop counter

ACP_Loop:
      mov   al, [InputBytes+si]     ; Read a byte from table

      cmp   al, 0FFh                ; If it is FF or E0 (low Byte of I/O
      je    NoArcNet                ;  address we will assume that we read
                                    ;  air.
      cmp   al, 0E0h
      je    NoArcNet

      and   al, 78h                 ; bits 6 through 3 (0XXX X000) should
                                    ;  be constant

      cmp   si, 0h                  ; Is it first byte read ?
      je    ACP_First_Pass

      cmp   ACP_First, al           ; is it equal to the first Byte read
      jne   NoArcNet

      inc   si                      ; point to next byte in table
      cmp   si, 4d                  ; have we done all four bytes
      je    ArcNetFound             ; Yes, we have found an Arcnet Card

      jmp   ACP_Loop

ACP_First_Pass:
      mov   ACP_First, al           
      inc   si                      ; point to next byte in table
      jmp   ACP_Loop
      

ArcNetFound:
      mov   ax, 1                   ; return TRUE
      jmp   short ACP_End

NoArcNet:
      xor   ax, ax                  ; return FALSE

ACP_End:
cEnd    ArcnetCardPresent

;*****************************************************************************
;
; LookForSerialMouse
;
;*****************************************************************************
LookForSerialMouse PROC NEAR

      mov       ax,CRT_Data_Seg         ; Get ROM BIOS Data segment.
      mov       es,ax                   ; Establish addressability to it.
      assume    es:nothing

      xor       di,di                   ; Assume starting at COM1

serial_try_again:
      mov       dx,es:[di]              ; Get base address of COM port to test.
      or        dx,dx                   ; Does this port exist?
      jnz       serial_test_port        ; Yes, go and test it.
      cmp       di,4                    ; If this is COM3 or COM4, use the
      jb        serial_next_port        ;  internal addresses for them.
      je        @F                      ; If we have COM3, DX=0.
      inc       dx                      ; If we have COM4, DX=2.
      inc       dx                      ; ...

@@:
      mov       bx,dx                   ; BX has index into our table.
      cmp       bx,2                    ; Are we about to look at COM4 ?
      jne       NotCom4

      cCall     ArcnetCardPresent
      or        ax,ax                   ; if Arcnet Present do not do
      jnz       No_Serial_Mouse         ;   COM4 test as the Arcnet Card will
                                        ;   be Reset.

NotCom4:
      mov       dx,COM_3_4_Addrs[bx]    ; Get base address of the COM port.

serial_test_port:
;
; First, do a quick test to make sure something out there responds like a
;       COM port.
;
      push      dx                      ; Save base address.
      address   IIR RXB                 ; Address Interrupt ID register.
      DelayIn   al,dx                   ; AL=contents of Interrupt ID reg.
      pop       dx                      ; Restore base address.
      test      al,0F8h                 ; Make sure bits 3-7 are all 0!
      jnz       serial_next_port        ; No COM port -> no mouse.

      call      TestForSerial           ; Is a serial mouse attached to port?
      cmp       ax,NO_MOUSE
      jne       Serial_Mouse_Found      ; Yes!

serial_next_port:                       ; No serial mouse on this COM port.
      add       di,2                    ; Otherwise, move to the next possible
      cmp       di,8                    ; port and try there.
      jb        serial_try_again        ; Look for COM1 through COM4.

No_Serial_Mouse:
      mov       ax,NO_MOUSE

Serial_Mouse_Found:
      ret

LookForSerialMouse ENDP

;*****************************************************************************
;
; TestForSerial
;
;*****************************************************************************
TestForSerial   PROC    NEAR

      call      SaveCOMSetting

      call      SetupCOMForMouse        ; Set up COM port to talk to mouse.

      mov       cx,SHORTDELAY           ; Use a short delay time.
      call      ResetSerialMouse        ; Reset mouse to see if it is there.
      cmp       ax,NO_MOUSE
      jne       TFS_Found

      mov       cx,LONGDELAY            ; Maybe the mouse is just slow.
      call      ResetSerialMouse        ; Reset mouse to see if it is there.
      cmp       ax,NO_MOUSE
      jne       TFS_Found

      call      TestForLogitechSerial   ; Maybe it's a Logitech Series C

TFS_Found:
      push      ax                      ; Save return value
      call      RestoreCOMSetting
      pop       ax
      ret

TestForSerial   ENDP

;*****************************************************************************
;
;       SaveCOMSetting
;
;       This procedure will save the current state of the COM port given.
;
;       ENTRY   DX              Base address of COM port.
;
;       EXIT    none
;
;       ALTERS  AX
;
;       CALLS   none
;


SaveCOMSetting  PROC    NEAR

        push    dx                      ; Save base I/O address.
        address LCR RXB                 ; Get address of Line Control Register.
        DelayIn al,dx                   ; Get current contents.
        mov     [LCRSave],al            ; Save them.
        or      al,LC_DLAB              ; Set up to access divisor latches.
        DelayOut dx,al
        address LATMSB LCR              ; Get address of high word of divisor
        DelayIn al,dx                   ; latch and save its current contents.
        mov     [LATMSBSave],al
        address LATLSB LATMSB           ; Get address of low word of divisor
        DelayIn al,dx                   ; latch and save its current contents.
        mov     [LATLSBSave],al
        address LCR LATLSB              ; Get address of Line Control Register
        mov     al,[LCRSave]            ; and disable access to divisor.
        and     al,NOT LC_DLAB
        DelayOut dx,al
        address MCR LCR                 ; Get address of Modem Control Register
        DelayIn al,dx                   ; and save its current contents.
        mov     [MCRSave],al
        address IER MCR                 ; Get address of Interrupt Enable Reg-
        DelayIn al,dx                   ; ister and save its current contents.
        mov     [IERSave],al
        pop     dx                      ; Restore base I/O address.
        ret

SaveCOMSetting  ENDP

;*****************************************************************************
;
;       RestoreCOMSetting
;
;       This procedure will restore the state of the COM port.
;
;       ENTRY   DX              Base address of COM port.
;
;       EXIT    none
;
;       ALTERS  AX
;
;       CALLS   none
;


RestoreCOMSetting       PROC    NEAR

        push    dx                      ; Save base I/O address.
        address LCR RXB                 ; Get address of Line Control Register.
        mov     al,LC_DLAB              ; Set up to access divisor latches.
        DelayOut dx,al
        address LATMSB LCR              ; Get address of high word of divisor
        mov     al,[LATMSBSave]         ; and restore it.
        DelayOut dx,al
        address LATLSB LATMSB           ; Get address of low word of divisor
        mov     al,[LATLSBSave]         ; and restore it.
        DelayOut dx,al
        address LCR LATLSB              ; Get address of Line Control Register
        mov     al,[LCRSave]            ; and restore it, disabling access to
        and     al,NOT LC_DLAB          ; the divisor latches.
        DelayOut dx,al
        address MCR LCR                 ; Get addres of Modem Control Register
        mov     al,[MCRSave]            ; and restore it.
        DelayOut dx,al
        address IER MCR                 ; Get address of Interrupt Enable Reg-
        mov     al,[IERSave]            ; ister and restore it.
        DelayOut dx,al
        pop     dx                      ; Restore base I/O address.
        ret

RestoreCOMSetting       ENDP

;*****************************************************************************
;
;       SetupCOMForMouse
;
;       This procedure will set up the given COM port so that it can talk to
;               a serial mouse.
;
;       ENTRY   DX              Base address of COM port to set up
;
;       EXIT    COM port set up, all interrupts disabled at COM port
;
;       ALTERS  AX
;
;       CALLS   none
;


SetupCOMForMouse        PROC    NEAR

        push    dx                      ; Save base I/O address.
        address LCR RXB                 ; Get address of Line Control Reg.
        mov     al,LC_DLAB              ; Set up to access divisor latches.
        DelayOut dx,al
        address LATMSB LCR              ; Get address of high word of divisor
        mov     al,HIGH DIV_1200        ; latch and set it with value for
        DelayOut dx,al                  ; 1200 baud.
        address LATLSB LATMSB           ; Get address of low word of divisor
        mov     al,LOW DIV_1200         ; latch and set it with value for
        DelayOut dx,al                  ; 1200 baud.
        address LCR LATLSB              ; Get address of Line Control Reg.
        mov     al,LC_BITS7 + LC_STOP1 + LC_PNONE
        DelayOut dx,al                  ; Set 7,n,1; disable access to divisor.
        address IER LCR                 ; Get address of Int. Enable Register
        xor     al,al                   ; Disable all interrupts at the COM
        DelayOut dx,al                  ; port level.
        address LSR IER                 ; Get address of Line Status Reg.
        DelayIn al,dx                   ; Read it to clear any errors.
        pop     dx                      ; Restore base I/O address
        ret

SetupCOMForMouse        ENDP

;*****************************************************************************
ResetSerialMouse2  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.
;

rsm2_waitloop:
        DelayIn al,dx                   ; Read and ignore any stray data.
        call    IsWaitOver              ; Determine if we've delayed enough.
        jnc     rsm2_waitloop            ; If not, keep waiting.

rsm2_waitover:
        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 3 characters that aren't
;       an M, we return a failure indication.
;

        address LSR MCR                 ; Get address of Line Status Reg.
        mov     si,0                    ; Read up to 3 chars from port.

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

        jmp     short rsm2_leave         ; Timed out. Leave with carry set.

rsm2_gotchar:
        address RXB LSR                 ; Get address of Receive Buffer.
        DelayIn al,dx                   ; Get character that was sent to us.
        mov     [SerialBuf+si],al
        address LSR RXB                 ; Oh well. Get address of LSR again.
        inc     si                      ; Have we read 3 chars yet?
        cmp     si,10d
        jne     rsm2_lookforM            ; Nope, we'll give him another try.

rsm2_leave:
        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

⌨️ 快捷键说明

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