home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mouprsrc.zip / PROTOCOL.ASM next >
Assembly Source File  |  2000-11-23  |  11KB  |  506 lines

  1. ; Mouse Protocol Analyzer for serial mice
  2. ; Copyright (c) 1997-2000 Nagy Daniel <nagyd@almos.vein.hu>
  3. ;
  4. ; This program is free software; you can redistribute it and/or modify
  5. ; it under the terms of the GNU General Public License as published by
  6. ; the Free Software Foundation; either version 2 of the License, or
  7. ; (at your option) any later version.
  8. ;
  9. ; This program is distributed in the hope that it will be useful,
  10. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ; GNU General Public License for more details.
  13. ;
  14. ; You should have received a copy of the GNU General Public License
  15. ; along with this program; if not, write to the Free Software
  16. ; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17. ;
  18.  
  19. ;
  20. ; History:
  21. ;
  22. ; 1.5 - by Arkady V.Belousov <ark@mos.ru>
  23. ;    Small bugfixes and optimizations
  24. ;    Mouse events bytes printing moved out from IRQ handler
  25. ; 1.4 - by Arkady V.Belousov <ark@mos.ru>
  26. ;    Only first argument (COM port number) now is required
  27. ; 1.3 - by Arkady V.Belousov <ark@mos.ru>
  28. ;    Added parsing and showing PNP data
  29. ; 1.2 - by Arkady V.Belousov <ark@mos.ru>
  30. ;    Source synchronized with CTMOUSE source
  31. ;    Added command line option for COM LCR value
  32. ;    Added dumping of reset sequence, generated by mouse
  33. ; 1.1 - Added command line option for COM port selection
  34. ; 1.0 - First public release
  35. ;
  36.  
  37. WARN
  38. .model tiny
  39.  
  40. j        equ    jmp short
  41.  
  42. movSeg        macro    dest,src
  43.         push    src
  44.         pop    dest
  45.     endm
  46.  
  47. saveFAR        macro    addr,segm,offs
  48.         mov    word ptr addr[0],offs
  49.         mov    word ptr addr[2],segm
  50.     endm
  51.  
  52. PrintS        macro    addr
  53.     IFNB <addr>
  54.      IFDIFI <addr>,<dx>
  55.         mov    dx,offset addr
  56.      ENDIF
  57.     ENDIF
  58.         mov    ah,9
  59.         int    21h
  60.     endm
  61.  
  62.  
  63. ;██████████████████████████████ DATA SEGMENT ██████████████████████████████
  64.  
  65. .data
  66.  
  67. oldIRQaddr    dd    ?        ; old IRQ handler address
  68.  
  69. CRLF2        db    0Dh,0Ah
  70. CRLF        db    0Dh,0Ah,'$'
  71. Syntax        db    'Syntax: protocol <COM (1-4)> [<bytes per event (3-5)> [<COM LCR value (2-3)>]]',0Dh,0Ah,'$'
  72. S_notCOM    db    'COM port not found!',0Dh,0Ah,'$'
  73.  
  74. S_COMinfo    db    '1200 bps, '
  75. databits    db    '5 data bits, '
  76. stopbits    db    '1 stop bit.'
  77.         db    0Dh,0Ah,'Reset:$'
  78. S_spaces    db    0Dh,0Ah,' '
  79. S_bitbyte    db         '     $'
  80. S_byte        db    '   $'
  81.  
  82. S_CRCerr    db    0Dh,0Ah,0Dh,0Ah,'PNP CRC error...$'
  83. S_manufact    db    0Dh,0Ah,0Dh,0Ah,'Manufacturer: $'
  84. S_product    db    0Dh,0Ah,'  Product ID: $'
  85. S_serial    db    0Dh,0Ah,'    Serial #: $'
  86. S_class        db    0Dh,0Ah,'       Class: $'
  87. S_driverid    db    0Dh,0Ah,'   Driver ID: $'
  88. S_username    db    0Dh,0Ah,'   User name: $'
  89.  
  90.  
  91. ;██████████████████████████████ CODE SEGMENT ██████████████████████████████
  92.  
  93. .code
  94.         org    100h
  95. start:        cld
  96.         mov    si,80h
  97.         lodsb
  98.         cbw                ; OPTIMIZE: instead MOV AH,0
  99.         mov    di,si
  100.         add    di,ax
  101.  
  102.         call    skipwhite
  103.         jc    HELP
  104.         mov    dx,offset DGROUP:S_notCOM
  105.         dec    ax            ; OPTIMIZE: AX instead AL
  106.         cmp    al,3
  107.         ja    EXITERRMSG
  108.         call    setCOMport
  109.         ;mov    dx,offset DGROUP:S_notCOM
  110.         jc    EXITERRMSG
  111.  
  112.         call    skipwhite
  113.         jc    @@start
  114.         mov    [limit],al
  115.  
  116.         call    skipwhite
  117.         jc    @@start
  118.         mov    [COMLCR],al
  119.  
  120.         call    skipwhite
  121.         jc    @@start
  122.  
  123. HELP:        mov    dx,offset DGROUP:Syntax
  124. EXITERRMSG:    PrintS
  125.         int    20h
  126. ;----------
  127. @@start:    mov    si,[IO_address]
  128.         call    disableCOM
  129.         call    resetmouse
  130.  
  131.         mov    al,[IRQintnum]        ; save old IRQ handler
  132.         mov    ah,35h
  133.         int    21h            ; get INT in ES:BX
  134.         saveFAR [oldIRQaddr],es,bx
  135.         mov    ah,25h            ; OPTIMIZE: instead MOV AX,word ptr [IRQintnum]
  136.         mov    dx,offset DGROUP:IRQhandler
  137.         int    21h            ; set INT in DS:DX
  138. ;==========
  139.         call    enableCOM
  140.         movSeg    es,ds
  141.         mov    bx,offset DGROUP:buffer
  142.  
  143. @@loop:        hlt
  144. @@loopbuffer:    cmp    bx,[buffer@]
  145.         je    @@kbdcheck
  146.  
  147.         cmp    bx,offset DGROUP:buffer+BUFFERSZ
  148.         jb    @@getbyte
  149.         mov    bx,offset DGROUP:buffer
  150. @@getbyte:    mov    ah,[bx]
  151.         inc    bx
  152.  
  153.         mov    di,offset DGROUP:S_bitbyte+1
  154.         mov    cx,8            ; 8 bits
  155. @@nextbit:    mov    al,'0' SHR 1
  156.         rol    ax,1
  157.         stosb
  158.         loop    @@nextbit
  159.         PrintS    DGROUP:S_bitbyte
  160.  
  161.         db    0B0h            ; MOV AL,byte
  162. IOdone        db    0            ; processed bytes counter
  163.         inc    ax            ; OPTIMIZE: AX instead AL
  164.         db    03Ch            ; CMP AL,byte
  165. limit        db    3
  166.         jb    @@nextdone
  167.         PrintS    DGROUP:CRLF
  168.         mov    al,0            ; zero counter
  169. @@nextdone:    mov    [IOdone],al
  170.         j    @@loopbuffer
  171.  
  172. @@kbdcheck:    mov    ah,1
  173.         int    16h
  174.         jz    @@loop
  175. ;==========
  176.         xor    ah,ah
  177.         int    16h
  178.  
  179.         call    disableCOM
  180.         db    0B8h            ; MOV AX,word
  181. IRQintnum    db    ?,25h            ; INT number of selected IRQ
  182.         lds    dx,[oldIRQaddr]
  183.         int    21h            ; set INT in DS:DX
  184.  
  185.         mov    ax,3533h
  186.         int    21h
  187.         mov    cx,es
  188.         jcxz    @@exit
  189.         xor    ax,ax
  190.         int    33h
  191. @@exit:        int    20h
  192.  
  193. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  194.  
  195. skipwhite    proc
  196.         cmp    si,di
  197.         jae    @retC
  198.         lodsb
  199.         cmp    al,' '
  200.         jbe    skipwhite
  201.         sub    al,'0'
  202.         jae    @@ret
  203.         jmp    HELP
  204. @retC:        stc
  205. @@ret:        ret
  206. skipwhite    endp
  207.  
  208. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  209.  
  210. setCOMport    proc
  211.         xor    bx,bx
  212.         mov    es,bx
  213.         mov    bl,al
  214.         shl    bx,1
  215.         mov    cx,es:400h[bx]
  216.         jcxz    @retC
  217.         mov    [IO_address],cx
  218.  
  219.         shr    al,1            ; 0=COM1, 1=COM2, ...
  220.         mov    al,4            ; IRQ4 for COM1/3
  221.         sbb    al,0            ; IRQ3 for COM2/4
  222.         mov    cl,al
  223.         add    al,8
  224.         mov    [IRQintnum],al
  225.         mov    al,1
  226.         shl    al,cl
  227.         mov    [PICstate],al        ; PIC interrupt disabler
  228.         not    al
  229.         mov    [notPICstate],al    ; PIC interrupt enabler
  230.         ;clc
  231.         ret
  232. setCOMport    endp
  233.  
  234.  
  235. ;█████████████████████████████ COMM ROUTINES ██████████████████████████████
  236.  
  237. disableCOM    proc
  238.         in    al,21h            ; {21h} get PIC mask
  239.         db    0Ch            ; OR AL,byte
  240. PICstate    db    ?            ; set bit to disable interrupt
  241.         out    21h,al            ; disable serial interrupts
  242. ;----------
  243.         mov    dx,si
  244.         add    dx,3
  245.         xor    ax,ax            ; {3FBh} LCR: DLAB off
  246.         out    dx,ax            ; {3FCh} MCR: DTR/RTS/OUT2 off
  247.         dec    dx
  248.         dec    dx
  249.         ;xor    ax,ax            ; {3F9h} IER: interrupts off
  250.         out    dx,ax            ; {3FAh} FCR: disable FIFO
  251.         ret
  252. disableCOM    endp
  253.  
  254. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  255.  
  256. enableCOM    proc
  257.         mov    dx,si
  258.         add    dx,3
  259.         db    0B8h            ; MOV AX,word
  260. COMLCR        db    2,00001011b        ; {3FBh} LCR: DLAB off, no
  261.         out    dx,ax            ;  parity, stop=1, length=7/8
  262.                         ; {3FCh} MCR: DTR/RTS/OUT2 on
  263.         dec    dx
  264.         dec    dx
  265.         mov    ax,1            ; {3F9h} IER: enable DR intr
  266.         out    dx,ax            ; {3FAh} FCR: disable FIFO
  267. ;----------
  268.         in    al,21h            ; {21h} get PIC mask
  269.         db    24h            ; AND AL,byte
  270. notPICstate    db    ?            ; clear bit to enable interrupt
  271.         out    21h,al            ; enable serial interrupts
  272.         ret
  273. enableCOM    endp
  274.  
  275. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  276.  
  277. resetmouse    proc
  278.         mov    al,[COMLCR]
  279.         mov    ah,al
  280.         and    al,3
  281.         add    [databits],al
  282.         shr    ah,3
  283.         adc    [stopbits],0
  284.         PrintS    DGROUP:S_COMinfo
  285. ;----------
  286.         mov    dx,si
  287.         add    dx,3
  288.         mov    al,80h
  289.         out    dx,al            ; {3FBh} LCR: DLAB on
  290.         xchg    dx,si
  291.         mov    ax,96            ; 1200 baud rate
  292.         out    dx,ax            ; {3F8h},{3F9h} divisor latch
  293.  
  294.         xchg    dx,si
  295.         mov    al,[COMLCR]
  296.         out    dx,al            ; {3FBh} LCR: set comm params
  297.  
  298.         inc    dx
  299.         push    dx
  300.         inc    dx            ; {3FDh} LSR: clear error bits
  301.         in    ax,dx            ; {3FEh} MSR: clear state bits
  302.         mov    dx,si
  303.         in    al,dx            ; {3F8h} flush receive buffer
  304.  
  305.         pop    dx            ; {3FCh} MCR (modem ctrl reg)
  306.         call    pulseRTS        ; drop and raise RTS signal
  307.  
  308. ;---------- read and show reset sequence, generated by mouse
  309.         mov    bx,20            ; output counter
  310.         mov    di,offset DGROUP:PNPdata
  311. @@inloop:    mov    cx,2+1            ; length of silence in ticks
  312.         mov    dx,si            ; (include rest of curr tick)
  313.         add    dx,5            ; DX=3FDh, SI=3F8h
  314.         push    di
  315. @@timeloop:    mov    di,es:[46Ch]
  316. @@waitloop:    in    al,dx            ; {3FDh} LSR (line status reg)
  317.         test    al,1
  318.         jnz    @@savebyte        ; jump if data ready
  319.         cmp    di,es:[46Ch]
  320.         je    @@waitloop        ; jump if same tick
  321.         loop    @@timeloop        ; wait next tick of silence
  322.         pop    di
  323.         j    @@parsePNP
  324.  
  325. ;---------- save and show next byte
  326. @@savebyte:    pop    di
  327.         mov    dx,si
  328.         in    al,dx            ; {3F8h} receive byte
  329.         cmp    di,sp
  330.         jae    @@showbyte
  331.         mov    [di],al
  332.         inc    di
  333. @@showbyte:    call    hexbyte2a
  334.         mov    word ptr S_byte[1],ax
  335.         PrintS    DGROUP:S_byte
  336.         dec    bx
  337.         jnz    @@inloop
  338.         PrintS    DGROUP:S_spaces
  339.         mov    bl,20
  340.         j    @@inloop
  341.  
  342. ;---------- parse and show PNP data
  343. @@parsePNP:    mov    cx,di
  344.         mov    di,offset DGROUP:PNPdata
  345.         sub    cx,di
  346.         jcxz    @@resetret
  347. @@findstart:    mov    al,[di]
  348.         cmp    al,'('-20h
  349.         je    @@startcrc
  350.         inc    di
  351.         loop    @@findstart
  352.         j    @@resetret
  353.  
  354. @@startcrc:    mov    bx,di
  355.         mov    al,0
  356. @@crcloop:    add    al,[di]
  357.         cmp    byte ptr [di],')'-20h
  358.         je    @@checkcrc
  359.         add    byte ptr [di],20h
  360.         inc    di
  361.         loop    @@crcloop
  362.         j    @@resetret
  363.  
  364. @@checkcrc:    dec    di
  365.         sub    al,[di]
  366.         dec    di
  367.         sub    al,[di]
  368.         add    al,20h+20h
  369.         call    hexbyte2a
  370.         cmp    ax,[di]
  371.         je    @@showPNP
  372.         PrintS    DGROUP:S_CRCerr
  373.         j    @@resetret
  374.  
  375. @@showPNP:    mov    cx,3
  376.         add    bx,cx
  377.         mov    dx,offset DGROUP:S_manufact
  378.         call    print1PNPfield
  379.         mov    cx,4
  380.         mov    dx,offset DGROUP:S_product
  381.         call    print1PNPfield
  382.         cmp    byte ptr [bx],'\'
  383.         jne    @@resetret
  384.         mov    dx,offset DGROUP:S_serial
  385.         call    print2PNPfield
  386.         mov    dx,offset DGROUP:S_class
  387.         call    print2PNPfield
  388.         mov    dx,offset DGROUP:S_driverid
  389.         call    print2PNPfield
  390.         mov    dx,offset DGROUP:S_username
  391.         call    print2PNPfield
  392.  
  393. @@resetret:    PrintS    DGROUP:CRLF2
  394.         ret
  395. resetmouse    endp
  396.  
  397. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  398.  
  399. pulseRTS    proc
  400.         xor    ax,ax
  401.         mov    es,ax
  402.         call    @@tickOUT        ; DTR/RTS/OUT2 off
  403.         mov    al,3            ; DTR/RTS on, OUT2 off
  404.  
  405. @@tickOUT:    mov    di,es:[46Ch]
  406. @@tickwait:    cmp    di,es:[46Ch]
  407.         je    @@tickwait        ; wait timer tick change
  408.         out    dx,al            ; {3FCh} MCR: change DTR/RTS
  409.         ret
  410. pulseRTS    endp
  411.  
  412. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  413.  
  414. print1PNPfield    proc
  415.         PrintS
  416.         mov    ah,2
  417. @@print1loop:    mov    dl,[bx]
  418.         inc    bx
  419.         int    21h
  420.         loop    @@print1loop
  421. @ret:        ret
  422. print1PNPfield    endp
  423.  
  424. print2PNPfield    proc
  425.         PrintS
  426.         mov    ah,2
  427. @@print2loop:    inc    bx
  428.         cmp    bx,di
  429.         jae    @ret
  430.         mov    dl,[bx]
  431.         cmp    dl,'\'
  432.         je    @ret
  433.         int    21h
  434.         j    @@print2loop
  435. print2PNPfield    endp
  436.  
  437. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  438. ;    Convert byte into unterminated ASCII hex-string with 2 digit
  439. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  440. ;
  441. ; In:    AL                    (value)
  442. ; Out:    AX                    (ASCII string, 2 hex digits)
  443. ; Use:    none
  444. ; Modf:    CX
  445. ; Call:    none
  446. ;
  447. hexbyte2a    proc
  448.         mov    ah,al
  449.         and    al,0Fh
  450.         cmp    al,10
  451.         sbb    al,69h
  452.         das
  453.         xchg    ah,al
  454.         mov    cl,4
  455.         shr    al,cl
  456.         cmp    al,10
  457.         sbb    al,69h
  458.         das
  459.         ret
  460. hexbyte2a    endp
  461.  
  462.  
  463. ;██████████████████████████████ IRQ HANDLER ███████████████████████████████
  464.  
  465. IRQhandler    proc
  466.         push    ax dx bx
  467.         db    0BAh            ; MOV DX,word
  468. IO_address    dw    ?            ; COM port IO address
  469.         push    dx
  470.         inc    dx
  471.         inc    dx
  472.         in    al,dx            ; {3FAh} IIR (intr id reg)
  473.         add    dx,3            ; {3FDh} LSR: clear error bits
  474.         in    ax,dx            ; {3FEh} MSR: clear state bits
  475.         pop    dx
  476.         xchg    bx,ax            ; OPTIMIZE: instead MOV BL,AL
  477.         in    al,dx            ; {3F8h} flush receive buffer
  478.  
  479.         shr    bl,1
  480.         jnc    @@exitIRQ        ; jump if data not ready
  481.         db    0BBh            ; MOV BX,word
  482. buffer@        dw    offset DGROUP:buffer
  483.         cmp    bx,offset DGROUP:buffer+BUFFERSZ
  484.         jb    @@putbyte
  485.         mov    bx,offset DGROUP:buffer
  486. @@putbyte:    mov    cs:[bx],al
  487.         inc    bx
  488.         mov    cs:[buffer@],bx
  489.  
  490. @@exitIRQ:    mov    al,20h
  491.         out    20h,al            ; {20h} end of interrupt
  492.         pop    bx dx ax
  493.         iret
  494. IRQhandler    endp
  495.  
  496.  
  497. ;██████████████████████████████████████████████████████████████████████████
  498.  
  499. .data        ; NOTE: data segment placed after code segment,
  500.         ; so PNPdata and buffer points right after program end
  501.  
  502. PNPdata        label    byte
  503. buffer        label    byte
  504. BUFFERSZ    equ    32
  505.         end    start
  506.