📄 md.asm
字号:
.MODEL medium
;***************************************************************************
;* *
;* MD.ASM Mouse detection code. *
;* *
;***************************************************************************
memM = 1 ; Medium Model
?WIN = 0 ; No windows prolog / epilog code (std epilog / prolog).
?PLM = 0 ; CPROC calling convention. NOT Pascal
INCLUDE cmacros.inc ;* must be version 2.09 or higher
INCLUDE md.inc
INCLUDE id.inc
cPublic MACRO n,c,a
cProc n,<PUBLIC, c>,<a>
ENDM
sBegin DATA
LATLSBSave db ?
LATMSBSave db ?
LCRSave db ?
MCRSave db ?
IERSave db ?
fSingle8259 db 0
SerialBuf db 10 dup (?)
SemaphoreWord dw ?
COM_3_4_ADDRS LABEL WORD
dw 03E8h
dw 02E8h
sEnd DATA
sBegin CODE
assumes CS, CODE
assumes DS, DATA
;*****************************************************************************
;
; int fnHardMouseDetect(void);
;
; This procedure what type of mouse is being used. It will determine
; that that type of mouse is present in the system and is working
; properly.
;
; ENTRY None.
;
; EXIT Mouse type in AX. or if AX = -1 the hardware will not support
; mouse detection.
;
; ALTERS AX, BX, CX, DX, SI, DI
;
; CALLS TestForInport
; IRQAvailable
; TestForBus
; TestForSerial
; TestForPS2
;
;*****************************************************************************
cProc fnHardMouseDetect <PUBLIC, FAR>, <ES, DS, SI, DI>
localW locvar1
cBegin fnHardMouseDetect
; First of all we need to know if the two int 15h call we need to make are
; supported on the hardware were running on. So, the setup_for_detect call
; will do just that, setup for the detection. If the call returns carry set
; then it's "game over man" because we won't have the int 15h calls we need.
call setup_for_detect
mov locvar1,-1
jc finished_mouse
; Now that we know the hardware will support the code used here to detect
; mice we can go about our business of detecing mice !!
;
mov locvar1,NO_MOUSE ; Initilize the return value.
;
; First try, we'll look for an inport mouse !
;
mov dx,INPORT_FIRST_PORT + 2 ; Get address of ID register.
inport_try_again:
call TestForInport ; Does an InPort exist at this address?
jnc inport_found ; No carry ! Inport found !
sub dx,4 ; Nope, try the next possible port.
cmp dx,INPORT_LAST_PORT + 2
jae inport_try_again
jmp short look_for_bus
inport_found:
mov locvar1,INPORT_MOUSE
jmp finished_mouse
;
; We enter this point if we couldn't find an InPort mouse in the system.
;
look_for_bus:
call TestForBus ; Does a Bus mouse exist in the system?
jc look_for_PS2 ; No, look for a PS/2 mouse.
mov locvar1,BUS_MOUSE ; Indicate bus mouse found.
jmp finished_mouse
;
; We enter this point if we couldn't find either an InPort
; mouse or a Bus mouse in the system.
;
look_for_PS2:
call LookForPS2Mouse
cmp ax,NO_MOUSE
je look_for_serial
mov locvar1,AX ; Yep! return mouse type !
jmp short finished_mouse
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; call TestForPS2 ; Does a PS/2 style mouse exist?
; jc look_for_serial ; Nope, check for serial mouse.
;
; mov locvar1,LT_PS2MOUSE ; Yep! return mouse type !
; jc finished_mouse ; Nope, leave with error.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; We enter this point if we couldn't find either an InPort
; mouse, a Bus mouse, or a PS/2 mouse in the system.
;
look_for_serial:
call LookForSerialMouse
mov locvar1, ax
finished_mouse:
mov ax,locvar1
cEnd fnHardMouseDetect
;*****************************************************************************
;
; setup_for_detect
;
; Procedure will assure that were ready to start the detection and that the
; hardware were running on will allow int 15h/86h (delay) and int 15h/C0h
; (Get system environment).
;
; ENTRY: None.
;
; EXIT: NC - All is well to begin detection.
; CY - Nope, int 15h calls needed are not available.
;
; ALTERS: AX ES BX CX DX And sets the fSingle8259 gloval var to true or false
; depending on weather there are multiple 8259 chips in the system.
;
setup_for_detect PROC NEAR
mov ah,0c0h ; int 15h - func get sys environment.
int 15h
jc old_machine
cmp word ptr es:[bx],5 ; Did we return 5 bytes ?
jb old_machine ; If not, no go.
mov ah,byte ptr es:[bx+5] ; Get the configuration flags.
test ah,01000000b ; Is bit 6 set ? (slave 8259 present ?)
mov fSingle8259,TRUE
jz All_is_well
mov fSingle8259,FALSE
jmp short All_is_well
; I know that since the int 15h/0C0h call failed, we have an old machine upon
; which I can assume will not have a slave 8259. If call int 15h/8300h will
; work we can still detect the mouse.
old_machine:
mov fSingle8259,TRUE
clc
All_is_well:
ret
setup_for_detect ENDP
;*****************************************************************************
;
; TestForInport
;
; This procedure will attempt to find an InPort mouse at the given base
; I/O address. Note that if an InPort is found, it will be left
; in a state where it will not be generating any interrupts.
;
; ENTRY DX I/O address of InPort Identification Register
;
; EXIT NC An Inport was found
; CY No Inport was found
;
; ALTERS AX, BX, CX, DX, SI
;
; CALLS FindInportInterrupt
;
TestForInport PROC NEAR
;
; Since the identification register alternates between returning back
; the Inport chip signature and the version/revision, if we have an
; InPort chip, the chip signature will be read in one of the following
; two reads. If it isn't, we do not have an InPort chip.
;
mov bl,INPORT_ID
in al,dx ; Read ID register.
cmp al,bl ; Is value the InPort chip signature?
je possible_inport ; Yes, go make sure we have an InPort.
in al,dx ; Read ID register again.
cmp al,bl ; Is value the InPort chip signature?
jne inport_not_found ; No, return error
;
; At this point, we managed to read the InPort chip signature, so we have
; a possible InPort chip. The next read from the ID register will
; return the version/revision. We then make sure that the ID register
; alternates between the chip signature and this version/revision. If
; it does, we have an InPort chip.
;
possible_inport:
in al,dx ; Read version/revision.
mov ah,al ; Save it.
mov cx,5 ; Test ID register 5 times.
inport_check:
in al,dx ; Read ID register.
cmp al,bl ; Make sure it is the chip signature.
jne inport_not_found ; If not, we don't have an InPort chip.
in al,dx ; Read ID register.
cmp al,ah ; Make sure version/revision is same.
jne inport_not_found ; If not, we don't have an InPort chip.
loop inport_check ; Test desired number of times.
clc
ret
;
; At this point, we know we have an InPort chip. We now try to determine
; what interrupt level it is jumpered at.
;
inport_not_found: ; We don't have an InPort chip.
stc ; Show failure.
ret ; Return to caller.
TestForInport ENDP
;*****************************************************************************
;
; TestForBus
;
; This procedure will attempt to find a bus mouse adaptor in the system
; and will return the results of this search.
;
; ENTRY None.
;
; EXIT NC Bus mouse adaptor was found
;
; CY Bus mouse not found.
;
; ALTERS AX, BX, CX, DX
;
; CALLS FindBusInterrupt
;
TestForBus PROC NEAR
;
; We determine if the bus mouse adaptor is present by attempting to
; program the 8255A, and then seeing if we can write a value out to
; Port B on the 8255A and get that value back. If we can, we assume
; that we have a bus mouse adaptor.
;
mov dx,BUS_INIT ; Get address of 8255A control port.
mov al,BUS_INIT_VALUE ; Get proper value.
out dx,al ; Set up 8255A.
IOdelay
mov ax,0A5A5h ; Get a signature byte and a copy.
address BUS_SIG BUS_INIT ; Get address of Port B.
out dx,al ; Set Port B with signature.
IOdelay
in al,dx ; Read back Port B.
IOdelay
cmp al,ah ; Does it match signature byte?
stc ; Set return for no bus mouse adaptor.
jne bus_not_found ; Nope - no bus mouse adaptor
clc
bus_not_found:
ret
TestForBus ENDP
;***************************************************************************
;*
;* ArcnetCardPresent - Detects the presence of an Arcnet Card
;*
;* ENTRY: None.
;*
;* EXIT: Boolean
;* AX = 1 , Arcnet Card Probably present
;* AX = 0 , Arcnet Card Probably NOT Present
;*
;***************************************************************************
cPublic ArcnetCardPresent <FAR,PUBLIC>,<SI,DX>
localV InputBytes, 4d
localV ACP_First, 1d
cBegin ArcnetCardPresent
; Read a BYTE from four different 16-bit I/O addresses that have
; the same lower 10 bits (2E0h). 2E0h is the address of the Status
; register for the Arcnet Cards that tend to be reset easily
; (a Read or write to I/O addresses 2E8, 2E9, 2EA, OR 2EB).
; Store the BYTE in InputBytes
;
mov dx, 56E0h
IOdelay
in al, dx
mov InputBytes, al
mov dx, 0AAE0h
IOdelay
in al, dx
mov InputBytes+1, al
mov dx, 0E2E0h
IOdelay
in al, dx
mov InputBytes+2, al
mov dx, 1EE0h
IOdelay
in al, dx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -