home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
mouprsrc.zip
/
PROTOCOL.ASM
next >
Wrap
Assembly Source File
|
2000-11-23
|
11KB
|
506 lines
; Mouse Protocol Analyzer for serial mice
; Copyright (c) 1997-2000 Nagy Daniel <nagyd@almos.vein.hu>
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
;
;
; History:
;
; 1.5 - by Arkady V.Belousov <ark@mos.ru>
; Small bugfixes and optimizations
; Mouse events bytes printing moved out from IRQ handler
; 1.4 - by Arkady V.Belousov <ark@mos.ru>
; Only first argument (COM port number) now is required
; 1.3 - by Arkady V.Belousov <ark@mos.ru>
; Added parsing and showing PNP data
; 1.2 - by Arkady V.Belousov <ark@mos.ru>
; Source synchronized with CTMOUSE source
; Added command line option for COM LCR value
; Added dumping of reset sequence, generated by mouse
; 1.1 - Added command line option for COM port selection
; 1.0 - First public release
;
WARN
.model tiny
j equ jmp short
movSeg macro dest,src
push src
pop dest
endm
saveFAR macro addr,segm,offs
mov word ptr addr[0],offs
mov word ptr addr[2],segm
endm
PrintS macro addr
IFNB <addr>
IFDIFI <addr>,<dx>
mov dx,offset addr
ENDIF
ENDIF
mov ah,9
int 21h
endm
;██████████████████████████████ DATA SEGMENT ██████████████████████████████
.data
oldIRQaddr dd ? ; old IRQ handler address
CRLF2 db 0Dh,0Ah
CRLF db 0Dh,0Ah,'$'
Syntax db 'Syntax: protocol <COM (1-4)> [<bytes per event (3-5)> [<COM LCR value (2-3)>]]',0Dh,0Ah,'$'
S_notCOM db 'COM port not found!',0Dh,0Ah,'$'
S_COMinfo db '1200 bps, '
databits db '5 data bits, '
stopbits db '1 stop bit.'
db 0Dh,0Ah,'Reset:$'
S_spaces db 0Dh,0Ah,' '
S_bitbyte db ' $'
S_byte db ' $'
S_CRCerr db 0Dh,0Ah,0Dh,0Ah,'PNP CRC error...$'
S_manufact db 0Dh,0Ah,0Dh,0Ah,'Manufacturer: $'
S_product db 0Dh,0Ah,' Product ID: $'
S_serial db 0Dh,0Ah,' Serial #: $'
S_class db 0Dh,0Ah,' Class: $'
S_driverid db 0Dh,0Ah,' Driver ID: $'
S_username db 0Dh,0Ah,' User name: $'
;██████████████████████████████ CODE SEGMENT ██████████████████████████████
.code
org 100h
start: cld
mov si,80h
lodsb
cbw ; OPTIMIZE: instead MOV AH,0
mov di,si
add di,ax
call skipwhite
jc HELP
mov dx,offset DGROUP:S_notCOM
dec ax ; OPTIMIZE: AX instead AL
cmp al,3
ja EXITERRMSG
call setCOMport
;mov dx,offset DGROUP:S_notCOM
jc EXITERRMSG
call skipwhite
jc @@start
mov [limit],al
call skipwhite
jc @@start
mov [COMLCR],al
call skipwhite
jc @@start
HELP: mov dx,offset DGROUP:Syntax
EXITERRMSG: PrintS
int 20h
;----------
@@start: mov si,[IO_address]
call disableCOM
call resetmouse
mov al,[IRQintnum] ; save old IRQ handler
mov ah,35h
int 21h ; get INT in ES:BX
saveFAR [oldIRQaddr],es,bx
mov ah,25h ; OPTIMIZE: instead MOV AX,word ptr [IRQintnum]
mov dx,offset DGROUP:IRQhandler
int 21h ; set INT in DS:DX
;==========
call enableCOM
movSeg es,ds
mov bx,offset DGROUP:buffer
@@loop: hlt
@@loopbuffer: cmp bx,[buffer@]
je @@kbdcheck
cmp bx,offset DGROUP:buffer+BUFFERSZ
jb @@getbyte
mov bx,offset DGROUP:buffer
@@getbyte: mov ah,[bx]
inc bx
mov di,offset DGROUP:S_bitbyte+1
mov cx,8 ; 8 bits
@@nextbit: mov al,'0' SHR 1
rol ax,1
stosb
loop @@nextbit
PrintS DGROUP:S_bitbyte
db 0B0h ; MOV AL,byte
IOdone db 0 ; processed bytes counter
inc ax ; OPTIMIZE: AX instead AL
db 03Ch ; CMP AL,byte
limit db 3
jb @@nextdone
PrintS DGROUP:CRLF
mov al,0 ; zero counter
@@nextdone: mov [IOdone],al
j @@loopbuffer
@@kbdcheck: mov ah,1
int 16h
jz @@loop
;==========
xor ah,ah
int 16h
call disableCOM
db 0B8h ; MOV AX,word
IRQintnum db ?,25h ; INT number of selected IRQ
lds dx,[oldIRQaddr]
int 21h ; set INT in DS:DX
mov ax,3533h
int 21h
mov cx,es
jcxz @@exit
xor ax,ax
int 33h
@@exit: int 20h
;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
skipwhite proc
cmp si,di
jae @retC
lodsb
cmp al,' '
jbe skipwhite
sub al,'0'
jae @@ret
jmp HELP
@retC: stc
@@ret: ret
skipwhite endp
;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
setCOMport proc
xor bx,bx
mov es,bx
mov bl,al
shl bx,1
mov cx,es:400h[bx]
jcxz @retC
mov [IO_address],cx
shr al,1 ; 0=COM1, 1=COM2, ...
mov al,4 ; IRQ4 for COM1/3
sbb al,0 ; IRQ3 for COM2/4
mov cl,al
add al,8
mov [IRQintnum],al
mov al,1
shl al,cl
mov [PICstate],al ; PIC interrupt disabler
not al
mov [notPICstate],al ; PIC interrupt enabler
;clc
ret
setCOMport endp
;█████████████████████████████ COMM ROUTINES ██████████████████████████████
disableCOM proc
in al,21h ; {21h} get PIC mask
db 0Ch ; OR AL,byte
PICstate db ? ; set bit to disable interrupt
out 21h,al ; disable serial interrupts
;----------
mov dx,si
add dx,3
xor ax,ax ; {3FBh} LCR: DLAB off
out dx,ax ; {3FCh} MCR: DTR/RTS/OUT2 off
dec dx
dec dx
;xor ax,ax ; {3F9h} IER: interrupts off
out dx,ax ; {3FAh} FCR: disable FIFO
ret
disableCOM endp
;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
enableCOM proc
mov dx,si
add dx,3
db 0B8h ; MOV AX,word
COMLCR db 2,00001011b ; {3FBh} LCR: DLAB off, no
out dx,ax ; parity, stop=1, length=7/8
; {3FCh} MCR: DTR/RTS/OUT2 on
dec dx
dec dx
mov ax,1 ; {3F9h} IER: enable DR intr
out dx,ax ; {3FAh} FCR: disable FIFO
;----------
in al,21h ; {21h} get PIC mask
db 24h ; AND AL,byte
notPICstate db ? ; clear bit to enable interrupt
out 21h,al ; enable serial interrupts
ret
enableCOM endp
;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
resetmouse proc
mov al,[COMLCR]
mov ah,al
and al,3
add [databits],al
shr ah,3
adc [stopbits],0
PrintS DGROUP:S_COMinfo
;----------
mov dx,si
add dx,3
mov al,80h
out dx,al ; {3FBh} LCR: DLAB on
xchg dx,si
mov ax,96 ; 1200 baud rate
out dx,ax ; {3F8h},{3F9h} divisor latch
xchg dx,si
mov al,[COMLCR]
out dx,al ; {3FBh} LCR: set comm params
inc dx
push dx
inc dx ; {3FDh} LSR: clear error bits
in ax,dx ; {3FEh} MSR: clear state bits
mov dx,si
in al,dx ; {3F8h} flush receive buffer
pop dx ; {3FCh} MCR (modem ctrl reg)
call pulseRTS ; drop and raise RTS signal
;---------- read and show reset sequence, generated by mouse
mov bx,20 ; output counter
mov di,offset DGROUP:PNPdata
@@inloop: mov cx,2+1 ; length of silence in ticks
mov dx,si ; (include rest of curr tick)
add dx,5 ; DX=3FDh, SI=3F8h
push di
@@timeloop: mov di,es:[46Ch]
@@waitloop: in al,dx ; {3FDh} LSR (line status reg)
test al,1
jnz @@savebyte ; jump if data ready
cmp di,es:[46Ch]
je @@waitloop ; jump if same tick
loop @@timeloop ; wait next tick of silence
pop di
j @@parsePNP
;---------- save and show next byte
@@savebyte: pop di
mov dx,si
in al,dx ; {3F8h} receive byte
cmp di,sp
jae @@showbyte
mov [di],al
inc di
@@showbyte: call hexbyte2a
mov word ptr S_byte[1],ax
PrintS DGROUP:S_byte
dec bx
jnz @@inloop
PrintS DGROUP:S_spaces
mov bl,20
j @@inloop
;---------- parse and show PNP data
@@parsePNP: mov cx,di
mov di,offset DGROUP:PNPdata
sub cx,di
jcxz @@resetret
@@findstart: mov al,[di]
cmp al,'('-20h
je @@startcrc
inc di
loop @@findstart
j @@resetret
@@startcrc: mov bx,di
mov al,0
@@crcloop: add al,[di]
cmp byte ptr [di],')'-20h
je @@checkcrc
add byte ptr [di],20h
inc di
loop @@crcloop
j @@resetret
@@checkcrc: dec di
sub al,[di]
dec di
sub al,[di]
add al,20h+20h
call hexbyte2a
cmp ax,[di]
je @@showPNP
PrintS DGROUP:S_CRCerr
j @@resetret
@@showPNP: mov cx,3
add bx,cx
mov dx,offset DGROUP:S_manufact
call print1PNPfield
mov cx,4
mov dx,offset DGROUP:S_product
call print1PNPfield
cmp byte ptr [bx],'\'
jne @@resetret
mov dx,offset DGROUP:S_serial
call print2PNPfield
mov dx,offset DGROUP:S_class
call print2PNPfield
mov dx,offset DGROUP:S_driverid
call print2PNPfield
mov dx,offset DGROUP:S_username
call print2PNPfield
@@resetret: PrintS DGROUP:CRLF2
ret
resetmouse endp
;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
pulseRTS proc
xor ax,ax
mov es,ax
call @@tickOUT ; DTR/RTS/OUT2 off
mov al,3 ; DTR/RTS on, OUT2 off
@@tickOUT: mov di,es:[46Ch]
@@tickwait: cmp di,es:[46Ch]
je @@tickwait ; wait timer tick change
out dx,al ; {3FCh} MCR: change DTR/RTS
ret
pulseRTS endp
;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
print1PNPfield proc
PrintS
mov ah,2
@@print1loop: mov dl,[bx]
inc bx
int 21h
loop @@print1loop
@ret: ret
print1PNPfield endp
print2PNPfield proc
PrintS
mov ah,2
@@print2loop: inc bx
cmp bx,di
jae @ret
mov dl,[bx]
cmp dl,'\'
je @ret
int 21h
j @@print2loop
print2PNPfield endp
;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
; Convert byte into unterminated ASCII hex-string with 2 digit
;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
;
; In: AL (value)
; Out: AX (ASCII string, 2 hex digits)
; Use: none
; Modf: CX
; Call: none
;
hexbyte2a proc
mov ah,al
and al,0Fh
cmp al,10
sbb al,69h
das
xchg ah,al
mov cl,4
shr al,cl
cmp al,10
sbb al,69h
das
ret
hexbyte2a endp
;██████████████████████████████ IRQ HANDLER ███████████████████████████████
IRQhandler proc
push ax dx bx
db 0BAh ; MOV DX,word
IO_address dw ? ; COM port IO address
push dx
inc dx
inc dx
in al,dx ; {3FAh} IIR (intr id reg)
add dx,3 ; {3FDh} LSR: clear error bits
in ax,dx ; {3FEh} MSR: clear state bits
pop dx
xchg bx,ax ; OPTIMIZE: instead MOV BL,AL
in al,dx ; {3F8h} flush receive buffer
shr bl,1
jnc @@exitIRQ ; jump if data not ready
db 0BBh ; MOV BX,word
buffer@ dw offset DGROUP:buffer
cmp bx,offset DGROUP:buffer+BUFFERSZ
jb @@putbyte
mov bx,offset DGROUP:buffer
@@putbyte: mov cs:[bx],al
inc bx
mov cs:[buffer@],bx
@@exitIRQ: mov al,20h
out 20h,al ; {20h} end of interrupt
pop bx dx ax
iret
IRQhandler endp
;██████████████████████████████████████████████████████████████████████████
.data ; NOTE: data segment placed after code segment,
; so PNPdata and buffer points right after program end
PNPdata label byte
buffer label byte
BUFFERSZ equ 32
end start