home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / MSDOS / PKTDRVR / PDCLK207.ZIP / PDCLKSRC / PING.ASM < prev    next >
Encoding:
Assembly Source File  |  1993-10-09  |  21.1 KB  |  1,028 lines

  1. ;        ping.asm
  2. ;========================================================================
  3.  
  4. ; Copyright (C) 1991 by Jan.Engvald@ldc.lu.se, see file COPYING.
  5.  
  6. MsgEchoHead    db    CR, LF, "Ping with packet size     "
  7. MsgEchoSweep    db    "<"
  8. MsgEchoSize    db    "0    and interval"
  9. MsgEchoMs    db    "     0  ms to "
  10. MsgEchoTarget    db    "1.2.3.4        :", CR, LF, LF
  11. MsgEchoStats    db    "───────── Packets ──────── ║ ────── Delay ms ────── ║   Packet  ║ Load ║  Time ", CR, LF
  12.         db    "transmit  receive     diff ║ this   min   avg   max ║    loss   ║ kb/s ║     s ", CR, LF, "$$"
  13. MsgEcho        db    "       0        0        0      0     0     0     0     0.0000 %     0       0 ", CR, '$'
  14. MsgEchoSeqEr    equ    MsgEcho+26
  15. MsgEchoTime    equ    $-11
  16. MsgEchoLen    equ    $-MsgEcho-2
  17.  
  18. MsgSerrTbl    dw    offset MsgSerrUnr
  19.         dw    offset MsgSerrObuf
  20.         dw    offset MsgSerrNoarp
  21.         dw    offset MsgSerrTimout
  22.         dw    offset MsgSerrNotraf
  23. SERRTABLEN    equ    $-MsgSerrTbl
  24.         dw    offset MsgSerrUnimpl
  25.  
  26. MsgSerrUnr    db    LF, "Host or net unreachable", CR, LF, '$'
  27. MsgSerrObuf    db    LF, "Temporarily out of buffers", CR, LF, '$'
  28. MsgSerrNoarp    db    LF, "Got no ARP reply", CR, LF, '$'
  29. MsgSerrTimout    db    LF, "Timeout", CR, LF, '$'
  30. MsgSerrNotraf    db    LF, "Received no traffic from destination", CR, LF, '$'
  31.  
  32. MsgSerrUnimpl    db    LF, "Send Error.", CR, LF, '$'
  33.  
  34. MsgCalling    db    "Calling nameserver(s)... $"
  35. MsgNameRep    db    "got reply in "
  36. MsgNameRepTim    db    "     ms.", CR, LF, '$'
  37. MsgBadName    db    LF, "Bad hostname (or no nameserver).$"
  38.  
  39. EchoLoadCnt    db    2
  40.         even
  41. EchoTarget    dw    0, 0            ; echo argument values
  42. EchoSize    dw    -50
  43. EchoInterval    dw    220
  44. EchoData    dw    101h
  45. EchoDataIncW    dw    1
  46. EchoMinSize    dw    IPHDRLEN+UDPHDRLEN+6
  47.  
  48. EchoStart    dw    0, 0, 0         ; echo variables
  49. EchoNext    dw    0
  50. EchoLastDispl    dw    0
  51. EchoLastHi    dw    0
  52. EchoMaxSize    dw    1500
  53. EchoAvgSum    dw    0, 0
  54. EchoFudge    dw    0
  55. EchoLoad    dw    0, 0
  56. EchoDrop    dw    0
  57. EchoBufSeg    dw    0
  58. EchoSeqRx    dw    0
  59. EchoTxTime    dw    0
  60. EchoRxTime    dw    0
  61. EchoErTmpTime    dw    0
  62. EchoErSeqHi    equ    EchoSizeVec+2
  63. EchoErSeqLo    equ    EchoSizeVec+4
  64. EchoErRepHi    equ    EchoSizeVec+6
  65. EchoErRepLo    equ    EchoSizeVec+8
  66. EchoErLosHi    equ    EchoSizeVec+10
  67. EchoErLosLo    equ    EchoSizeVec+12
  68. EchoErTmp    equ    EchoSizeVec+14
  69. EchoLastErr    dw    0
  70. PingRowCnt    dw    17
  71. k51200        dw    51200
  72. k54925        dw    54925
  73. k64000        dw    64000
  74. EchoLoadTime    dw    0, 0
  75.  
  76. EchoTxHi    dw    0            ; echo display variables
  77. EchoTxLo    dw    0
  78. EchoRxHi    dw    0
  79. EchoRxLo    dw    0
  80. EchoDifHi     dw    0
  81. EchoDifLo     dw    0
  82. EchoThis    dw    0
  83. EchoMin     dw    0ffffh
  84. EchoAvg     dw    0
  85. EchoMax     dw    0
  86. EchoLoss    dw    0, 0
  87. EchoElapsed    dw    0, 0
  88.  
  89.  
  90. ;************************************************************************
  91. ;*        EchoAwhile
  92. ;************************************************************************
  93.  
  94. EchoAwhile    proc    near
  95.         assume    ds:code_s
  96.         call    HwTicksNoHi
  97.         mov    EchoStart,si        ; note start ticks
  98.         mov    EchoStart+2,dx
  99.         mov    EchoLoadTime,dx
  100.  
  101.         mov    di,offset EchoSizeVec    ; clear error size table
  102.         mov    cx,(EchoSizeEnd-EchoSizeVec)/2
  103.         xor    ax,ax
  104.         rep    stosw
  105.  
  106.         cmp    EchoTarget,ax        ; want to ping someone?
  107.         jne    EchoYes
  108.  
  109.         test    ArgFlags,TERM_WAIT    ; ping serving?
  110.         jz    EchoNo
  111.  
  112.         mov    dx,offset MsgEchoStats
  113.         call    DosPr$
  114.                 or      GenFlags,ECHO_DISPL
  115.   EchoNo:
  116.         ret
  117.  
  118.   EchoYes:
  119.         call    InitTimer        ; prepare millisecond timing
  120.  
  121.         mov    ax,ArgFlags
  122.         and    ax,STOP_ON_ERR
  123.         xor    ax,NO_ERR_YET+STOP_ON_ERR+NO_DROP_YET
  124.         or    GenFlags,ax
  125.  
  126.         call    HardwareTicks
  127.         mov    EchoStart,si        ; note start ticks
  128.         mov    EchoStart+2,dx
  129.         mov    EchoStart+4,ax
  130.         mov    EchoLoadTime,dx
  131.         mov    EchoLoadTime+2,ax
  132.         mov    si,dx
  133.  
  134.         call    DblShrX
  135.         mov    EchoNext,ax
  136.  
  137.         cmp    EchoTarget,127        ; dns lookup to do?
  138.         jne    EchoIpAddr
  139.  
  140.         mov    dx,offset MsgCalling
  141.         call    DosPr$
  142.  
  143.         mov    dx,2345h        ; ping udp src port
  144.         xor    ax,ax            ; NsId
  145.         mov    si,offset EchoNameBuf    ; Ns question string
  146.  
  147.         call    NsResolve        ; call nameserver(s)
  148.  
  149.         call    HardwareTicks        ; response time
  150.         mov    si,dx
  151.         sub    ax,EchoStart+4
  152.         sbb    dx,EchoStart+2
  153.         div    kTimerScale
  154.         mov    di,offset MsgNameRepTim
  155.         call    PutNumD4Fb
  156.  
  157.         mov    dx,offset MsgNameRep    ; display it.
  158.         call    DosPr$
  159.  
  160.         cmp    EchoTarget,127        ; name resolved?
  161.         jne    EchoIpAddr
  162.   EchoErrTerm:
  163.         mov    dx,offset MsgBadName
  164.         mov    al,'e'-'0'
  165.         call    PrTerminate
  166.   
  167.   EchoIpAddr:
  168.         mov    EchoTxTime,si        ; intialize timers
  169.         mov    EchoRxTime,si
  170. if TBLBUILD
  171.         test    ArgFlags,MAKE_TABLE
  172.         jz    EchoNotTbl
  173.         call    TableReady        ; allow tablebuilding now
  174.   EchoNotTbl:
  175. endif ; TBLBUILD
  176.                 or      GenFlags,ECHO_DISPL
  177.  
  178.         mov    ax,EchoInterval        ; check interval
  179.         test    ArgFlags,NOT_SAFE
  180.         jnz    EchoAsIs
  181.  
  182.         cmp    ax,128
  183.         jge    EchoAsItIs
  184.         mov    ax,128
  185.   EchoAsItIs:
  186.         test    ArgFlags,MICRO_100
  187.         jz    EchoAsIs
  188.         cmp    ax,128*10
  189.         jge    EchoAsIs
  190.         mov    ax,128*10
  191.   EchoAsIs:
  192.         mov    EchoInterval,ax
  193.  
  194.         call    BufAlloc        ; get a send buf
  195.         assume    ds:nothing
  196.         jz    EchoErrTerm
  197.  
  198.         call    MakeSendDescr
  199.  
  200.         mov    [di].uIcmpTypeCode,8    ; type = echo request
  201.         test    cs:GenFlags,UDP_ECHO
  202.         jz    EchoUseIcmp
  203.  
  204.         mov    word ptr cs:MsgEchoHead+2,'cE'
  205.         mov    word ptr cs:MsgEchoHead+4,'oh'
  206.         mov    word ptr [di].uUdpSrc,0703h    ; my udp echo port
  207.         mov    word ptr [di].uUdpDst,0900h    ; dst discard port
  208.         test    cs:ArgFlags,UDP_DISCARD
  209.         jnz    EchoUseIcmp
  210.         mov    word ptr [di].uUdpDst,0700h ; dst echo port
  211.   EchoUseIcmp:
  212.         mov    cx,cs:MyGiant        ; fill buffer with data
  213.                 sub     cx,HWHDRLEN+IPHDRLEN+ICMPHDRLEN+6
  214.         shr    cx,1
  215.         add    di,ICMPHDRLEN+6
  216.         mov    ax,cs:EchoData
  217.   EchoFillLoop:
  218.         stosw
  219.         add    ax,cs:EchoDataIncW
  220.         loop    EchoFillLoop
  221.   EchoFillEnd:
  222.         mov    dx,cs:EchoTarget    ; set IP destination
  223.         mov    ax,cs:EchoTarget+2
  224.         call    SetIpDst
  225.  
  226.         mov    ds,cs:MySegm
  227.         assume    ds:code_s
  228.         mov    EchoBufSeg,es
  229.  
  230.         mov    si,offset EchoTarget
  231.         mov    di,offset MsgEchoTarget
  232.         call    PutIpNum        ; tell who we are pinging
  233.  
  234.         mov    dx,EchoMinSize
  235.         sub    dx,IPHDRLEN
  236.         cmp    dx,ICMPHDRLEN+6
  237.         jns    EchoMinOK
  238.         mov    dx,ICMPHDRLEN+6
  239.   EchoMinOK:
  240.         mov    ax,EchoSize
  241.         neg    ax
  242.         jns    EchoSizeNeg
  243.         mov    dx,GIANTTR
  244.         neg    ax
  245.         mov    MsgEchoSweep,' '
  246.   EchoSizeNeg:
  247.                 mov     cx,MyGiant
  248.                 sub     cx,HWHDRLEN+IPHDRLEN+ICMPHDRLEN+6
  249.                 sub     ax,IPHDRLEN+ICMPHDRLEN+6
  250.                 cmp     ax,cx
  251.         jbe    EchoOkSize
  252.         xor    ax,ax
  253.   EchoOkSize:
  254.         add    ax,ICMPHDRLEN+6
  255.         mov    EchoSize,ax
  256.         mov    EchoMaxSize,ax
  257.  
  258.         cmp    dx,ax
  259.         jbe    EchoMinMax
  260.         mov    dx,ax
  261.   EchoMinMax:
  262.         mov    EchoMinSize,dx
  263.  
  264.         cmp    ax,dx
  265.         je    EchoFixedSz
  266.         push    ax
  267.         mov    ax,dx
  268.         add    ax,IPHDRLEN
  269.         mov    di,offset MsgEchoSweep-4
  270.         call    PutNumD4Fb        ;   and the min size used
  271.         pop    ax
  272.   EchoFixedSz:
  273.         add    ax,IPHDRLEN
  274.         mov    di,offset MsgEchoSize
  275.         mov    PutMinDigits,1
  276.         call    PutNum            ;   and the packet size used
  277.  
  278.         mov    ax,EchoInterval
  279.         push    ax
  280.         mov    di,offset MsgEchoMs
  281.         mov    PutMinDigits,6
  282.         call    PutNumFb        ;   and interval in ms
  283.         pop    ax
  284.         test    ArgFlags,MICRO_100
  285.         jz    Echo1ms
  286.         mov    dh,MsgEchoMs+5
  287.         mov    dl,'.'
  288.         mov    word ptr MsgEchoMs+5,dx
  289.         mul    k51200            ; make interval close to 0.1 ms
  290.         jmp    short EchoPrHdr
  291.   Echo1ms:
  292.         mul    k64000            ; make interval close to 1 ms
  293.   EchoPrHdr:
  294.         div    k54925
  295.         mov    EchoInterval,ax
  296.         mov    dx,offset MsgEchoHead
  297.         call    DosPr$
  298.  
  299.   EchoLoop:
  300.         call    Something2Do        ; process other things
  301.  
  302.         test    GenFlags,NO_ERR_YET+CONT_ON_ERR    ; want to stop on sequence errs?
  303.         jz    EchoEnd0
  304.  
  305.         call    AnyKey            ; first key stops sending
  306.         jz    EchoNoKey
  307.   EchoEnd0:
  308.         jmp    EchoEnd
  309.   EchoNoKey:
  310.         call    Something2Do        ; called to slow down client
  311.  
  312.         call    HardwareTicks
  313.         mov    es,EchoBufSeg
  314.         mov    di,es:[bx].dPtrUdp
  315.         mov    es:[di].uUdpData,ax
  316.         mov    es:[di].uUdpData+2,dx
  317.  
  318.         call    DblShrX
  319.         mov    dx,EchoNext
  320.         cmp    ax,dx            ; time to send next echo pkt?
  321.         js    EchoLoop
  322.  
  323.         add    dx,EchoInterval
  324.         cmp    dx,ax
  325.         jns    EchoSetNext
  326.         mov    dx,ax
  327.   EchoSetNext:
  328.         mov    EchoNext,dx        ; next send time
  329.  
  330.         mov    dx,es:[di].uUdpData+2
  331.         mov    EchoTxTime,dx
  332.  
  333.         mov    cx,EchoSize        ; compute packet size
  334.         inc    cx
  335.         cmp    cx,EchoMaxSize
  336.         jbe    EchoNormSize
  337.         mov    cx,EchoMinSize
  338.   EchoNormSize:
  339.         mov    EchoSize,cx
  340.  
  341.         mov    di,cx             ; IP data length
  342.         shl    di,1
  343.         inc    word ptr EchoSizeVec[di]
  344.  
  345.         mov    ax,EchoTxLo        ; increment send counters
  346.         add    ax,1
  347.         mov    EchoTxLo,ax
  348.         adc    EchoTxHi,0
  349.         mov    EchoFudge,1
  350.  
  351.         mov    ds,EchoBufSeg
  352.         assume    ds:nothing
  353.         mov    di,[bx].dPtrUdp        ; put sequence number
  354.         mov    [di].uUdpData+4,ax
  355.         mov    [bx].dPktLen,cx        ; and IP data length
  356.  
  357.         test    cs:GenFlags,UDP_ECHO
  358.         jnz    EchoUdp
  359.         call    SendIcmpPkt        ; send icmp echo pkt
  360.   EchoLoop8:
  361.         mov    ds,cs:MySegm
  362.         assume    ds:code_s
  363.         jnz    EchoErr         ; any errors?
  364.   EchoLoop9:
  365.         mov    EchoLastErr,cx
  366.         jmp    EchoLoop
  367.  
  368.   EchoUdp:
  369.         call    SendUdpPkt        ; send udp echo pkt
  370.         jmp    short EchoLoop8
  371.  
  372.   EchoErr:
  373.         cmp    cx,EchoLastErr
  374.         je    EchoLoop9
  375.  
  376.         push    cx
  377.         xor    ch,ch
  378.         test    cl,01            ; odd errs not allowed
  379.         jnz    EchoErrUndef
  380.         cmp    cl,SERRTABLEN
  381.         jb    EchoErrExist
  382.   EchoErrUndef:
  383.         mov    cl,SERRTABLEN
  384.   EchoErrExist:
  385.         mov    si,cx
  386.         mov    dx,MsgSerrTbl[si]
  387.         call    DosPr$
  388.         pop    cx
  389.         mov    ds,EchoBufSeg
  390.         test    ArgFlags,TERM_WAIT
  391.         jnz    EchoLoop9
  392.  
  393.   EchoEnd:
  394.         mov    ds,EchoBufSeg
  395.         assume    ds:nothing
  396.         call    BufRelease        ; release send buffer
  397.         push    cs
  398.         push    cs
  399.         pop    ds
  400.         assume    ds:code_s
  401.         pop    es
  402.  
  403.         mov    EchoFudge,0
  404.         or    ArgFlags,TERM_WAIT    ; allow late packets to arrive
  405.         ret
  406. EchoAwhile    endp
  407.  
  408.  
  409.  
  410. if DEBUG or TBLBUILD
  411. TstEqual    proc    near
  412.         assume    ds:nothing
  413.         jne    TstErr
  414.         ret
  415. TstEqual    endp
  416. endif ; DEBUG or TBLBUILD
  417.  
  418. if DEBUG
  419.  
  420.   TstBufLinks    proc    near
  421.         assume    ds:nothing
  422.         ja    TstErr
  423.         mov    si,di
  424.         inc    cx
  425.     TstLinkLoop:
  426. if DEBUG ge 6
  427.         .386
  428.         push    di
  429.         push    eax
  430.         push    cx
  431.  
  432.         cmp    di,offset FreeBufs
  433.         je    BufChkEnd
  434. ifdef SMALLBUFS
  435.         cmp    di,offset FreeSmal
  436.         je    BufChkEnd
  437. endif ; SMALLBUFS
  438.         push    ax
  439.         mov    cx,(dHwDst-dPtrIp)/4
  440. if DEBUG ge 8
  441.         mov    cx,((dHwDst-dPtrIp)+(BUFSIZESML-DESCRLEN))/4
  442.         mov    ax,es:[di].dHomeList
  443.         cmp    ax,offset FreeBufs
  444.         jne    BufChkSml
  445.         mov    cx,((dHwDst-dPtrIp)+(BUFSIZE-DESCRLEN))/4
  446.   BufChkSml:
  447. endif ; DEBUG ge 8
  448.         lea    di,[di].dPtrPhys
  449.         mov    eax,0aaaaaaaah        ; contents changed?
  450.         scasw
  451.         repe    scasd
  452.         pop    ax
  453.         call    TstEqual
  454.   BufChkEnd:
  455.         pop    cx
  456.         pop    eax
  457.         pop    di
  458.  
  459.         mov    bp,bx
  460.         mov    ax,dx
  461.         mov    bx,di
  462.         mov    dx,es
  463.         .8086
  464. endif ; DEBUG ge 6
  465.         les    di,es:[di].dNext
  466.         lds    si,[si].dPrev
  467.         loop    TstLinkLoop
  468.  
  469.         cmp    si,di
  470.         jne    TstErr
  471.         mov    cx,ds
  472.         cmp    cx,cs:MySegm
  473.         jne    TstErr
  474.         ret
  475. TstBufLinks    endp
  476.  
  477. endif ; DEBUG
  478.  
  479. TstErr:
  480.         call    Terminate
  481.  
  482.  
  483.  
  484. ;************************************************************************
  485. ;*        EchoDisplay
  486. ;************************************************************************
  487.  
  488.  
  489. EchoDisplay    proc    near
  490.         assume    ds:code_s
  491. if DEBUG or TBLBUILD
  492.         mov    al,'s'-'0'
  493.         cmp    word ptr StackLow,0    ; stack overflowed?
  494.         call    TstEqual
  495. endif ; DEBUG or TBLBUILD
  496.  
  497. if DEBUG
  498.         mov    al,'t'-'0'
  499.         cmp    word ptr phd_dioa,0    ; stack overflowed?
  500.         call    TstEqual
  501.  
  502.         mov    al,'i'-'0'
  503.         test    GenFlags,DBGINTERR    ; any interrupt debug errs?
  504.         call    TstEqual
  505.  
  506.         mov    cx,MyNbufs        ; any buffers damaged?
  507.         mov    bx,offset BufStart
  508.         mov    al,'u'-'0'
  509.   BufTestLoop:
  510.         cmp    [bx].dHomeList,offset FreeBufs
  511.         call    TstEqual
  512.         add    bx,MyBufSize
  513.         loop    BufTestLoop
  514.  
  515.         push    cs
  516.         pop    es
  517.         mov    di,offset FreeBufs
  518.         cli
  519.         mov    cx,[di].lBufsAvail
  520.         cmp    cx,MaxAvail
  521.         call    TstBufLinks
  522.         cmp    di,offset FreeBufs
  523.         call    TstEqual
  524.         sti
  525.  
  526. ifdef SMALLBUFS
  527.         mov    bx,offset BufStart+NBUFS*BUFSIZE
  528.         mov    cx,NBUFSMALL
  529.         mov    al,'v'-'0'
  530.   TstSmlLoop:
  531.         cmp    [bx].dHomeList,offset FreeSmal
  532.         call    TstEqual
  533.         add    bx,BUFSIZESML
  534.         loop    TstSmlLoop
  535.  
  536.         cli
  537.         mov    di,offset FreeSmal
  538.         mov    cx,[di].lBufsAvail
  539.         cmp    cx,NBUFSMALL
  540.         call    TstBufLinks
  541.         cmp    di,offset FreeSmal
  542.         call    TstEqual
  543.         sti
  544. endif ; SMALLBUFS
  545. endif ; DEBUG
  546.  
  547. if TBLBUILD
  548.         cmp    EchoTarget,0        ; are we pinging?
  549.         jne    EchoDispYes
  550.         test    ArgFlags,MAKE_TABLE
  551.         jz    EchoDispYes
  552.         call    TblDisplay        ; -no, must be tbl building
  553.         ret
  554.  
  555.   EchoDispYes:                    ; -yes, we are pinging
  556. endif ; TBLBUILD
  557.                 test    GenFlags,ECHO_DISPL
  558.                 jz      EchoDispRet
  559.  
  560.         mov    cx,SavedTicks
  561.         shr    cx,1
  562.         shr    cx,1
  563.         mov    ax,EchoLastDispl
  564.         shr    ax,1
  565.         shr    ax,1
  566.         cmp    ax,cx            ; time to update display?
  567.         jne    EchoDispNow
  568.   EchoDispRet:
  569.         ret
  570.  
  571.   EchoDispNow:
  572.         cli
  573.         mov    dx,EchoAvgSum
  574.         mov    ax,EchoAvgSum+2
  575.         mov    cx,EchoRxHi
  576.         mov    bx,EchoRxLo
  577.         sti
  578.         call    AdjTo16Bits
  579.         jz    EchoSkipAvg        ; avoid div by zero
  580.  
  581.         div    bx
  582. if DEBUG ge 2
  583.         mov    ax,MinAvail        ; Show min available bufs
  584. endif ; DEBUG ge 2
  585.         mov    EchoAvg,ax        ; average delay
  586.   EchoSkipAvg:
  587.  
  588.         cmp    EchoTarget,0
  589.         jne    $+5
  590.         jmp    EchoDspDiscard
  591.  
  592.         mov    dx,EchoTxHi        ; compute difference tx - rx
  593.         mov    ax,EchoTxLo
  594.         sub    ax,EchoFudge        ;   subtract one if just
  595.         sbb    dx,0            ;   sent a pkt
  596.         push    ax
  597.         push    dx
  598.         cli
  599.         sub    ax,EchoRxLo
  600.         sbb    dx,EchoRxHi
  601.         sti
  602.         jns    EchoDifPos        ; use abs(tx-rx)
  603.         call    NegDxAx
  604.   EchoDifPos:
  605.         mov    EchoDifHi,dx
  606.         mov    EchoDifLo,ax
  607.  
  608.         and    GenFlags,not PING_DELAY
  609.         mov    si,EchoMax        ; convert ms delay to ticks
  610.         or    si,si
  611.         jnz    EchoGotMax
  612.         mov    si,2000
  613.   EchoGotMax:
  614.         add    si,500
  615.         mov    cl,5            ;   with a margin
  616.         shr    si,cl
  617.         push    si            ;   and save it
  618.  
  619.         mov    cx,EchoTxTime
  620.         add    cx,si
  621.         add    si,EchoRxTime
  622.         cmp    cx,SavedTicks        ; did we stop a while ago?
  623.         js    EchoDispLoss        ; - yes, use diff
  624.  
  625.         cmp    si,EchoTxTime        ; received anything lately?
  626.         jns    EchoUseLoss        ; - yes
  627.  
  628.         and    GenFlags,not (NO_ERR_YET+NO_DROP_YET) ; - no, he
  629.         jmp    short EchoDispLoss    ;    probably died
  630.   EchoUseLoss:
  631.         mov    ax,word ptr EchoErLosLo    ; use loss cntr
  632.         mov    dx,word ptr EchoErLosHi
  633.         or    GenFlags,PING_DELAY+NO_DROP_YET
  634.   EchoDispLoss:
  635.         mov    cl,2            ; compute packet loss
  636.         call    DblShl            ;   multiply by 100
  637.         mov    si,dx
  638.         mov    bx,ax
  639.         mov    cl,3
  640.         call    DblShl
  641.         add    bx,ax
  642.         adc    si,dx
  643.         shl    ax,1
  644.         rcl    dx,1
  645.         add    ax,bx
  646.         adc    dx,si
  647.  
  648.         pop    si
  649.         pop    cx
  650.         pop    bx
  651.  
  652.         call    AdjTo16Bits
  653.         jz    EchoSkipLoss        ; avoid div by zero
  654.  
  655.         div    bx
  656.         mov    EchoLoss,ax
  657.  
  658.         mov    ax,dx            ;   fractional loss
  659.         mul    k10000
  660.         div    bx
  661.         mov    EchoLoss+2,ax
  662.   EchoSkipLoss:
  663.         shr    si,1
  664.         add    si,EchoErTmpTime
  665.         cmp    si,SavedTicks
  666.         jns    EchoDspTmp
  667.         cli
  668.         mov    ax,word ptr EchoErTmp    ; make temp err permanent
  669.         add    word ptr EchoErLosLo,ax
  670.         xor    ax,ax
  671.         adc    word ptr EchoErLosHi,ax
  672.         mov    word ptr EchoErTmp,ax
  673.         sti
  674.   EchoDspTmp:
  675.  
  676.   EchoDspDiscard:
  677.         push    cs            ; edit echo values
  678.         pop    es
  679.  
  680.         mov    di,offset MsgEcho-1
  681.         mov    si,offset EchoTxHi
  682.         mov     PutNumFiller,' '
  683.         mov    PutMinDigits,9
  684.         mov    cx,3
  685.         call    PutBigNums        ; tx and rx and diff
  686.  
  687.         mov    PutMinDigits,6
  688.         inc    di
  689.         mov    cx,5
  690.   EchoDispLoop:
  691.         push    cx
  692.         mov    cl,1
  693.         call    PutNums         ; delays and loss
  694.         pop    cx
  695.         loop    EchoDispLoop
  696.  
  697.         inc    di
  698.         mov    cl,1
  699.         mov    PutMinDigits,4
  700.         call    PutNumsF0        ; .0000%
  701.  
  702.         call    HardwareTicks
  703.         push    dx
  704.         push    si
  705.  
  706.         dec    EchoLoadCnt        ; update load every 2:nd time
  707.         jnz    EchoLoad1st
  708.  
  709.         mov    EchoLoadCnt,2
  710.         mov    bx,ax
  711.         mov    cx,dx
  712.         sub    ax,EchoLoadTime+2
  713.         sbb    dx,EchoLoadTime
  714.         mov    EchoLoadTime+2,bx
  715.         mov    EchoLoadTime,cx
  716.         js    EchoLoad1st        ; avoid overflow
  717.  
  718.         div    kTimerScale
  719.         mov    bx,ax
  720.         cli
  721.         mov    ax,EchoLoad+2
  722.         mov    dx,EchoLoad
  723.         mov    EchoLoad+2,0
  724.         mov    EchoLoad,0
  725.         sti
  726.         mov    cl,3
  727.         call    DblShl
  728.         div    bx
  729.         add    di,3
  730.         inc    PutMinDigits
  731.         call    PutNumFb        ; load kb/s
  732.   EchoLoad1st:
  733.         pop    dx            ; compute elapsed time
  734.         pop    ax
  735.         cmp    dx,EchoLastHi
  736.         jae    EchoLastGrows
  737.  
  738.         mov    bx,EchoLastDispl
  739.         mov    cx,EchoLastHi
  740.         sub    EchoStart+2,bx
  741.         sbb    EchoStart,cx
  742.   EchoLastGrows:
  743.         mov    EchoLastDispl,ax
  744.         mov    EchoLastHi,dx
  745.         sub    ax,EchoStart+2
  746.         sbb    dx,EchoStart
  747.         mov    cl,4            ; divide # of ticks by 18.2
  748.         call    DblShr
  749.         mov    EchoElapsed+2,ax
  750.         mov    EchoElapsed,dx
  751.         mov    cl,3
  752.         call    DblShr
  753.         sub    EchoElapsed+2,ax
  754.         sbb    EchoElapsed,dx
  755.         mov    cl,5
  756.         call    DblShr
  757.         add    ax,EchoElapsed+2
  758.         adc    dx,EchoElapsed
  759.         mov     PutNumFiller,' '
  760.         mov    PutMinDigits,8
  761.         mov    di,offset MsgEchoTime
  762.         call    PutBigNum        ; elapsed time
  763. if DEBUG
  764.         mov    dx,280h+10h        ; assume WD card at IO 280h
  765.         xor    ax,ax
  766.         xor    cx,cx
  767.         cli
  768.         out    dx,al            ; set page 0
  769.         call    IoDelay
  770.         add    dx,0eh
  771.         in    al,dx            ; readnadclear bad CRC ctr
  772.         add    cx,ax
  773.         inc    dx
  774.         in    al,dx            ; readandclear lost frames ctr
  775.         sti
  776.         add    cx,ax
  777.         add    EchoDrop,cx        ; add out of bufs ctr
  778. endif ; DEBUG
  779.         mov    ax,EchoDrop
  780. if DEBUG eq 0
  781.         or    ax,ax
  782.         jz    EchoNoDrops
  783. endif ; DEBUG eq 0
  784.         mov    di,offset MsgEcho+18    ; place before diff
  785.         mov    PutMinDigits,1
  786.         call    PutNum            ; show dropped packets
  787.         mov    byte ptr [di],' '
  788.   EchoNoDrops:
  789.         xor    si,si
  790.         cmp    word ptr EchoErRepLo,si    ; any repeated pkts?
  791.         jz    EchoDispNoRep
  792.         inc    si
  793.   EchoDispNoRep:
  794.         test    GenFlags,NO_DROP_YET
  795.         jz    EchoDispDrop
  796.         mov    dx,word ptr EchoErLosLo    ; any lost packet events?
  797.         or    dx,word ptr EchoErTmp
  798.         jz    EchoDispNoLoss
  799.   EchoDispDrop:
  800.         lodsw                ; add    si,2
  801.   EchoDispNoLoss:
  802.         cmp    word ptr EchoErSeqLo,0    ; any out of sequence?
  803.         jz    EchoDispInSeq
  804.         lodsw                ; add    si,4
  805.         lodsw
  806.   EchoDispInSeq:
  807.         mov    al,EchoErrChar[si]
  808.         mov    MsgEchoSeqEr,al        ; put rep/seq/lost char
  809.  
  810. if 1
  811.         test    ArgFlags,AVOID_HDWR
  812.         jnz    EchoDspDos
  813.  
  814.         test    GenFlags,GOT_DSP_ROW
  815.         jnz    EchoDspGotRow
  816.  
  817.         mov    ah,15            ; get screen mode
  818.         int    10h            ; call video BIOS
  819.         cmp    al,7            ; is it mono?
  820.         mov    dx,0b000h
  821.         jz    K1            ; yes
  822.         mov    dh,0b8h            ; no, set for color
  823.   K1:
  824.         mov    EchoDispPar,dx
  825.  
  826.         mov    ah,03h
  827.         xor    bx,bx
  828.         int    10h            ; get current row
  829.         mov    al,160
  830.         mul    dh
  831.         mov    EchoDspRow,ax
  832.         or    GenFlags,GOT_DSP_ROW
  833.   EchoDspGotRow:
  834.         mov    di,EchoDspRow
  835.         push    es
  836.         mov    es,EchoDispPar
  837.         mov    si,offset MsgEcho
  838.         mov    cx,MsgEchoLen
  839.         mov    ax,es:[di]
  840.   EchoDspL1:
  841.         lodsb                ; display echo values
  842.         stosw
  843.         loop    EchoDspL1
  844.  
  845.         pop    es
  846.         jmp    short EchoDspRet
  847.   EchoDspDos:
  848. endif
  849.         mov    dx,offset MsgEcho    ; display echo values
  850.         call    DosPr$
  851.   EchoDspRet:
  852.         ret
  853.  
  854.   EchoDispPar    dw    0b800h
  855.   EchoDspRow    dw    (25-1)*160
  856. EchoDisplay    endp
  857.  
  858.  
  859. ;                  seq   lost   rep
  860. EchoErrChar    db    ' '    ;   0      0     0  space
  861.         db    0eh    ;   0      0     1  double music note
  862.         db    '.'    ;   0      1     0  dot
  863.         db    ':'    ;   0      1     1  colon (double dot)
  864.         db    "'"    ;   1      0     0  apostrophe
  865.         db    '"'    ;   1      0     1  quote (double apostrophe)
  866.         db    '!'    ;   1      1     0  exclamation mark
  867.         db    13h    ;   1      1     1  double exclamation mark
  868.  
  869.  
  870.  
  871. ;************************************************************************
  872. ;*        AdjTo16Bits
  873. ;************************************************************************
  874.  
  875.   Adjust:
  876.         shr    dx,1            ; shift 32 bits right
  877.         rcr    ax,1
  878.         shr    cx,1
  879.         rcr    bx,1
  880. AdjTo16Bits:
  881.         or    cx,cx            ; fits in 16 bits?
  882.         jnz    Adjust
  883.         or    dx,dx
  884.         jnz    Adjust
  885.         or    bx,bx            ; avoid div by zero
  886.         ret
  887.  
  888.  
  889.  
  890. ;************************************************************************
  891. ;*        DblShrX
  892. ;************************************************************************
  893.  
  894. DblShrX     proc    near
  895.         mov    cl,7
  896.         test    ArgFlags,MICRO_100
  897.         jnz    DblShr
  898. DblShr10:
  899.         mov    cl,10
  900. DblShr:
  901.         xor    ch,ch
  902.   DblShrNext:
  903.         shr    dx,1            ; shift 32 bits right
  904.         rcr    ax,1
  905.         loop    DblShrNext
  906.         ret
  907. DblShrX     endp
  908.  
  909.  
  910.  
  911. ;************************************************************************
  912. ;*        DblShl
  913. ;************************************************************************
  914.  
  915. DblShl        proc    near
  916.         xor    ch,ch
  917.   DblShlNext:
  918.         shl    ax,1            ; shift 32 bits left
  919.         rcl    dx,1
  920.         loop    DblShlNext
  921.         ret
  922. DblShl        endp
  923.  
  924.  
  925.  
  926. ;************************************************************************
  927. ;*        EchoCalc
  928. ;************************************************************************
  929.  
  930.         even
  931. kTimerScale    dw    TimerResolution
  932.  
  933. EchoCalc    proc    near
  934.         assume    ds:nothing
  935.         mov    si,[bx].dPktLen     ; update error size table
  936.  
  937.         mov    cx,ds            ; save ds in cx until return
  938.         mov    es,cx
  939.         mov    ds,cs:MySegm
  940.         assume    ds:code_s
  941.  
  942.         shl    si,1
  943.         dec    word ptr EchoSizeVec[si]
  944.  
  945.         add    EchoRxLo,1        ; increment receive counters
  946.         adc    EchoRxHi,0
  947.         mov    EchoFudge,0
  948.  
  949.         mov    ax,EchoSeqRx
  950.         inc    ax
  951.         cmp    ax,es:[di].uUdpData+4    ; packet in sequence?
  952.         jne    EchoCalcChkSeq
  953.   EchoCalcInSeq:
  954.         mov    EchoSeqRx,ax
  955.   EchoCalcDelay:
  956.         call    HardwareTicks        ; compute delay
  957.         mov    EchoRxTime,dx
  958.         sub    ax,es:[di].uUdpData
  959.         sbb    dx,es:[di].uUdpData+2
  960.         js    EchoCalcRet
  961.         div    kTimerScale
  962.         mov    EchoThis,ax        ; delay for this packet
  963.  
  964.         add    EchoAvgSum+2,ax
  965.         adc    EchoAvgSum,0
  966.  
  967.         cmp    ax,EchoMin
  968.         jb    EchoSetMin
  969.   EchoChkMax:
  970.         cmp    ax,EchoMax
  971.         ja    EchoSetMax
  972.   EchoCalcRet:
  973.         ret
  974.  
  975.   EchoSetMin:
  976.         mov    EchoMin,ax        ; minimum delay
  977.         jmp    short EchoChkMax
  978.   EchoSetMax:
  979.         mov    EchoMax,ax        ; maximum delay
  980.         ret
  981.  
  982.   EchoCalcNonSeq:
  983.         and    GenFlags,not NO_ERR_YET
  984.         jmp    short EchoCalcDelay
  985.  
  986.   EchoCalcChkSeq:
  987.         js    EchoCalcDrop        ; missing packet(s)?
  988.  
  989.         dec    ax
  990.         cmp    ax,es:[di].uUdpData+4    ; repeat of latest packet?
  991.         je    EchoCalcRepeat
  992.  
  993.         add    word ptr EchoErSeqLo,1    ; inc out of sequence cntr
  994.         adc    word ptr EchoErSeqHi,0
  995.  
  996.         mov    dx,word ptr EchoErTmp
  997.         dec    dx
  998.         js    EchoLostMain        ; use tmp or main counter?
  999.         mov    word ptr EchoErTmp,dx
  1000.         jmp    short EchoCalcNonSeq
  1001.   EchoLostMain:
  1002.         sub    word ptr EchoErLosLo,1    ; after all: wasn't lost
  1003.         sbb    word ptr EchoErLosHi,0
  1004.         jmp    short EchoCalcNonSeq
  1005.   EchoCalcRepeat:
  1006.         add    word ptr EchoErRepLo,1    ; inc repeated pkts cntr
  1007.         adc    word ptr EchoErRepHi,0
  1008.         jmp    short EchoCalcNonSeq
  1009.   EchoCalcDrop:
  1010.         mov    dx,es:[di].uUdpData+4
  1011.         mov    EchoSeqRx,dx
  1012.         sub    dx,ax
  1013.         mov    ax,word ptr EchoErTmp
  1014.         or    ax,ax            ; old or new occurance?
  1015.         jnz    EchoDropMore
  1016.         mov    si,SavedTicks
  1017.         mov    EchoErTmpTime,si    ; -new, initialize timer
  1018.   EchoDropMore:
  1019.         add    ax,dx
  1020.         mov    word ptr EchoErTmp,ax    ; add to temporary drops
  1021.         jmp    EchoCalcNonSeq
  1022. EchoCalc    endp
  1023.  
  1024.  
  1025.  
  1026. ;========================================================================
  1027. ;        endinclude
  1028.