home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / msvp98b1.lzh / MSNTNI.ASM < prev    next >
Assembly Source File  |  1992-07-04  |  19KB  |  724 lines

  1.     NAME    MSNTNI
  2. ; File MSNTNI.ASM
  3. ; Telnet interface to MS-DOS Kermit
  4. ;
  5. ;  Copyright (C) 1985, 1992, Trustees of Columbia University in the 
  6. ;  City of New York.  Permission is granted to any individual or institution
  7. ;  to use this software as long as it is not sold for profit.  This copyright
  8. ;  notice must be retained.  This software may not be included in commercial
  9. ;  products without written permission of Columbia University.
  10. ; Written by Joe R. Doupnik, Utah State University, 
  11. ;  jrd@cc.usu.edu, jrd@usu.Bitnet.
  12. ;
  13. ; Edit history
  14. ; 6 Sept 1991 version 3.11
  15. ; Last edit 28 Jan 1992
  16.     include    mssdef.h
  17.  
  18. getintv    equ    35h        ; DOS get interrupt vector to es:bx
  19. bapicon    equ    0a0h        ; 3Com BAPI, connect to port
  20. bapidisc equ    0a1h        ; 3Com BAPI, disconnect
  21. bapiwrit equ    0a4h        ; 3Com BAPI, write block
  22. bapiread equ    0a5h        ; 3Com BAPI, read block
  23. bapibrk    equ    0a6h        ; 3Com BAPI, send short break
  24. bapistat equ    0a7h        ; 3Com BAPI, read status (# chars to be read)
  25. bapihere equ    0afh        ; 3Com BAPI, presence check
  26. bapieecm equ    0b0h        ; 3Com BAPI, enable/disable ECM char
  27. bapiecm    equ    0b1h        ; 3Com BAPI, trap Enter Command Mode char
  28.  
  29. data    segment public 'kdata'
  30.     extrn    tcptos:word    ; top of stack for TCP code
  31.     extrn    flags:byte, yflags:byte, portval:word, ttyact:byte
  32. ;[HF]    extrn    ftogmod:dword, 
  33.     extrn    crt_lins:byte, crt_cols:byte
  34. data    ends
  35.  
  36. _TEXT    SEGMENT  WORD PUBLIC 'CODE'
  37. _TEXT    ENDS
  38. _DATA    SEGMENT  WORD PUBLIC 'DATA'
  39. _DATA    ENDS
  40. CONST    SEGMENT  WORD PUBLIC 'CONST'
  41. CONST    ENDS
  42. _BSS    SEGMENT  WORD PUBLIC 'BSS'
  43. _BSS    ENDS
  44. DGROUP    GROUP    CONST, _BSS, _DATA
  45.     ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP
  46.  
  47. _DATA      SEGMENT
  48.     public _kmyip, _knetmask, _kdomain, _kgateway, _kns1, _kns2, _khost
  49.     public _kbcast, _bapibuf, _bapireq, _bapiret, _msgcnt, _msgbuf
  50.     public    _display_mode, _kport, _kpdint, _kserver, _kdebug, _kterm
  51.     public    _ktttype, _kterm_lines, _kterm_cols
  52.  
  53.     extrn    _my_ip_addr:dword, _sin_mask:dword
  54.  
  55.         db 'DUMMY',0           ; null pointer guard
  56. _kmyip        db 33 dup (0)        ; our IP number
  57. _knetmask    db 33 dup (0)        ; our netmask
  58. _kdomain    db 33 dup (0)        ; our domain
  59. _kgateway     db 33 dup (0)        ; our gateway
  60. _kns1        db 33 dup (0)        ; our nameserver #1
  61. _kns2        db 33 dup (0)        ; our nameserver #2
  62. _khost        db 61 dup (0)        ; remote host name/IP #
  63. _kbcast        db 33 dup (0)        ; broadcast IP
  64. _ktttype    db 33 dup (0)        ; terminal-type override string
  65. _kserver    dw    0        ; non-zero for Kermit server
  66. _kport        dw    23        ; TCP port (Telnet = 23)
  67. _kpdint        dw    0        ; Packet Driver Int, 0 = search
  68. _kdebug        dw    0        ; if SET DEBUG ON is effective
  69. _kterm        dw    0        ; terminal type index, see mssdef.h
  70. _kterm_lines    db    0        ; terminal screen height (24)
  71. _kterm_cols    db    0        ; terminal screen width (80)
  72. oldint8    dd    0            ; original Int 8 owner
  73. tcpstack dd    0            ; TCP code stack
  74. stack8    dd    0            ; stack at Int 8 invokation
  75. kstack    dw    0            ; Kermit mainline stack pointer
  76. tempax    dw    0            ; a temp
  77. tcpflag    db    0        ; who is running TCP code: 1=Kermit, 2=Int 8
  78. tcpdata    dw    0            ; Kermit offset of "tcpdata" block
  79. int8cnt    db    0            ; Int 8 times called counter
  80. _display_mode db 0            ; msg, none if == 0
  81. opcode    db    0            ; BAPI op code
  82. userbuf    dd    0            ; BAPI user's comms buffer address
  83. _bapireq dw    0            ; BAPI count of chars requested
  84. _bapiret dw    0            ; BAPI count of chars processed
  85. buflen    equ    512
  86. _bapibuf db    buflen dup (0)        ; BAPI buffer in TCP address space
  87.     db    buflen dup (0)        ;[HF] for guard
  88. _msgcnt    dw    0            ; count of bytes in msg buffer
  89. _msgbuf    db    256 dup (0)        ; interrupt level msg buffer
  90. _DATA      ENDS
  91.  
  92.  
  93. _TEXT    segment
  94.     ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP
  95.     extrn    _serial_handler:near, _main:near, _exit:near 
  96.     extrn    _pkt_release:near, _tcp_tick:near, _bcopy:near, _itoa:near
  97.     extrn    _strlen:near, _strcpy:near
  98.  
  99. public    _enable
  100. enable    proc    near
  101. _enable    equ    this byte
  102.     sti
  103.     ret
  104. enable    endp
  105.  
  106. public    _disable
  107. disable    proc    near
  108. _disable equ    this byte
  109.     cli
  110.     ret
  111. disable    endp
  112.  
  113. ; Hook Interrupts 8h. Return AX = 1 if successful else 0.
  114.     public    _hookvect
  115. hookvect proc    near
  116. _hookvect equ    this byte
  117.     push    bp
  118.     mov    bp,sp
  119.     mov    ax,bp
  120.     add    ax,2+2            ; C sp just before this call
  121.     mov    word ptr tcpstack,ax    ; save as main prog stack level
  122.     push    es
  123.     mov    ah,getintv        ; get interrupt vector
  124.     mov    al,8            ; vector number
  125.     int    dos
  126.     mov    ax,es
  127.     mov    cx,cs
  128.     cmp    ax,cx            ; points to us now?
  129.     je    hook2            ; e = yes, do not touch
  130.     mov    word ptr DGROUP:oldint8+2,ax    ; save segment
  131.     mov    word ptr DGROUP:oldint8,bx    ; save offset
  132.     mov    dx,offset ourtimer     ; new handler
  133.     push    ds
  134.     mov    ax,cs            ; segment
  135.     mov    ds,ax
  136.     mov    al,8            ; for Int 8
  137.     mov    ah,25H            ; set interrupt address from ds:dx
  138.     int    dos
  139.     pop    ds
  140. hook2:    mov    tcpflag,1     ; say Kermit but not Int 8 is running TCP
  141.     mov    ax,1            ; return 1 for success
  142.     pop    es
  143.     pop    bp
  144.     ret
  145. hook3:    call    unhookvect        ; put any back
  146.     xor    ax,ax            ; return 0 for failure
  147.     pop    es
  148.     pop    bp
  149.     ret
  150. hookvect endp
  151.  
  152.     public    _unhookvect
  153. unhookvect proc    near
  154. _unhookvect equ    this byte
  155.     push    bp
  156.     mov    bp,sp
  157.     push    es
  158.     push    bx
  159.     push    cx
  160.     clc
  161.     mov    tempax,0        ; assume failure status
  162.     mov    ah,getintv        ; get interrupt vector
  163.     clc
  164.     mov    al,8            ; vector number
  165.     int    dos
  166.     jc    unhook2            ; c = failed
  167.     mov    ax,es            ; es:bx is current owner, us?
  168.     mov    cx,cs
  169.     cmp    ax,cx            ; seg should be right here
  170.     jne    unhook2            ; ne = is not
  171.     cmp    bx,offset ourtimer    ; should be the same too
  172.     jne    unhook2            ; ne = is not, let them have the int
  173.     mov    ax,word ptr DGROUP:oldint8+2    ; segment
  174.     mov    dx,word ptr DGROUP:oldint8    ; offset
  175.     mov    cx,dx
  176.     or    cx,ax            ; was it used by us?
  177.     jz    unhook2            ; z = no, leave alone
  178.     push    ds
  179.     mov    ds,ax
  180.     mov    al,8            ; for Int 8
  181.     mov    ah,25H            ; set interrupt address from ds:dx
  182.     int    dos
  183.     pop    ds
  184.     and    tcpflag,not 2        ; Int 8 no longer touches TCP
  185.     mov    word ptr DGROUP:oldint8,0
  186.     mov    word ptr DGROUP:oldint8+2,0
  187.     mov    tempax,1        ; success status
  188.     jmp    short unhook3
  189. unhook2:mov    tempax,0        ; failure
  190. unhook3:mov    ax,tempax        ; return status (1=success, 0=fail)
  191.     pop    cx
  192.     pop    bx
  193.     pop    es
  194.     pop    bp
  195.     ret
  196. unhookvect endp
  197.  
  198. ; Int 8 routine to call the TCP code if Kermit main body does not.
  199. ourtimer proc near
  200.     push    ds
  201.     push    ax
  202.     mov    ax,dgroup        ; set addressibility to our dgroup
  203.     mov    ds,ax
  204.     pushf                ; simulate interrupt invokation
  205.     call    dword ptr DGROUP:oldint8 ; call previous owner of Int 8
  206.  
  207.     mov    ax,DGROUP        ; set addressibility to our dgroup
  208.     mov    ds,ax
  209.     test    tcpflag,1+2        ; is TCP code running now?
  210.     jnz    ourtim2            ; nz = yes, so we don't run now
  211.     mov    al,int8cnt        ; get our times-called counter
  212.     inc    al            ; up once again
  213. ;[HF]    and    al,7            ; keep 3 bits, about .5 sec @18.2tic/s
  214.     and    al,63            ;[HF] keep 5 bits, abuot .64 sec
  215.     mov    int8cnt,al        ; store
  216.     or    al,al            ; is it zero?
  217.     jnz    ourtim2            ; nz = no, go away for awhile
  218.     or    tcpflag,2        ; say we are running the TCP code
  219.     push    bp
  220.     push    bx
  221.     push    cx
  222.     push    dx
  223.     push    si
  224.     push    di
  225.     push    es
  226.     cli
  227.     mov    ax,ss
  228.     mov    word ptr stack8+2,ax    ; save current stack
  229.     mov    word ptr stack8,sp
  230.     mov    ax,word ptr tcpstack+2    ; get TCP stack seg
  231.     mov    ss,ax            ; set to TCP stack
  232.     mov    sp,word ptr tcpstack
  233.     sti                ; restart interrupts
  234.     xor    ax,ax            ; socket pointer, null
  235.     push    ax            ; set call frame for tcp_tick(NULL)
  236.     call    _tcp_tick        ; process some incoming packets
  237.     pop    ax            ; clean call frame
  238.     mov    ax,word ptr stack8+2    ; get original stack seg
  239.     cli
  240.     mov    ss,ax
  241.     mov    sp,word ptr stack8
  242.     sti
  243.     pop    es
  244.     pop    di
  245.     pop    si
  246.     pop    dx
  247.     pop    cx
  248.     pop    bx
  249.     pop    bp
  250.     and    tcpflag,not 2        ; finished our running of TCP code
  251. ourtim2:pop    ax
  252.     pop    ds
  253.     iret
  254. ourtimer endp
  255.  
  256. ; This routine is invoked from outside by a Far call. Enter with the caller's
  257. ; registers but our CS. Switch stacks and data segments.
  258. ; This version supports 3Com BAPI calls and does the near/far stuff via
  259. ; a local buffer.
  260.     public    ktcpcom
  261. ktcpcom     proc    FAR            ; i/o service routine
  262.     assume    ds:DGROUP
  263.     push    ds
  264.     push    ax
  265.     mov    ax,dgroup        ; set addressibility to our dgroup
  266.     mov    ds,ax
  267.     pop    ax
  268.     test    tcpflag,2        ; is Int 8 running TCP?
  269.     jz    ourser8            ; z = no, should never be yes, but...
  270.     mov    ah,1            ; say no char written
  271.     xor    cx,cx            ; chars written
  272.     pop    ds
  273.     ret
  274.  
  275. ourser8:or    tcpflag,1        ; say we are running TCP
  276.     push    es            ; save regs on the user's stack
  277.     push    di
  278.     push    si
  279.     push    dx
  280.     push    bx
  281.     push    bp
  282.     push    ax
  283.     mov    ax,dgroup        ; set addressibility to our dgroup
  284.     mov    ds,ax
  285.     pop    ax
  286.     mov    kstack,sp        ; remember caller's stack now
  287.     mov    sp,word ptr tcpstack    ; move to our TCP stack
  288.     mov    word ptr userbuf,bx    ; remember caller's es:bx
  289.     mov    word ptr userbuf+2,es
  290.     mov    _bapireq,cx        ; requested char count to TCP code
  291.     mov    _bapiret,0        ; init returned CX char count
  292.     mov    opcode,ah        ; remember operation for return proc
  293.     cmp    ah,bapihere        ; presence check?
  294.     jne    ourser6            ; ne = no
  295.     mov    ax,0af01h        ; return this value
  296.     jmp    ourser4            ; done
  297.  
  298. ourser6:
  299.     cmp    ah,bapiwrit        ; BAPI write?
  300.     jne    ourser2            ; ne = no
  301.     push    ax
  302.     push    cx
  303.     push    es
  304.     push    ds
  305.     mov    di,offset DGROUP:_bapibuf ; where it goes
  306.     mov    si,bx            ; es:bx, whence it comes
  307.     mov    bx,es
  308.     mov    ax,ds
  309.     mov    es,ax
  310.     mov    ds,bx
  311.     cld
  312.     cmp    cx,buflen        ; largest block i/o we allow here
  313.     jbe    ourser1            ; be = ok
  314.     mov    cx,buflen        ; truncate the request
  315. ourser1:shr    cx,1
  316.     jnc    ourser1a
  317.     movsb
  318. ourser1a:rep    movsw            ; copy their buffer to ours
  319.     pop    ds
  320.     pop    es
  321.     pop    cx
  322.     pop    ax
  323. ourser2:cmp    ah,bapiread        ; read?
  324.     jne    ourser3            ; ne = no
  325.     cmp    _msgcnt,0        ; any outstanding msgs from TCP?
  326.     je    ourser3            ; e = no msgs
  327.     call    oursmsg            ; send back the msgs instead
  328.     jmp    short ourser4        ; ax has status of ok
  329. ourser3:sti                ; let other ints happen
  330.     mov    bx,dgroup        ; set up es to dgroup too
  331.     mov    es,bx            ; bx is not needed at this time
  332.     xchg    ah,al            ; put function code in al
  333.     xor    ah,ah
  334.     push    ax            ; setup call frame
  335.  
  336.     call    _serial_handler        ; a near call, _serial_handler(ax)
  337.  
  338.     cli                ; reg ax has return status
  339.     add    sp,2            ; clean stack
  340.     mov    cx,dgroup        ; safety check, not really needed
  341.     mov    ds,cx
  342.     mov    cx,_bapiret        ; count of chars returned
  343.     cmp    opcode,bapiread        ; BAPI read?
  344.     jne    ourser4            ; ne = no
  345.     jcxz    ourser4            ; z = nothing to copy
  346.     push    ax
  347.     push    cx
  348.     mov    si,offset DGROUP:_bapibuf ; whence it comes
  349.     mov    di,word ptr userbuf    ; where it goes
  350.     mov    ax,word ptr userbuf+2    ; segment
  351.     mov    es,ax
  352.     cld
  353.     shr    cx,1
  354.     jnc    ourser3a
  355.     movsb
  356. ourser3a:rep    movsw            ; copy our buffer to theirs
  357.     pop    cx            ; return count in cx
  358.     pop    ax            ; return result code in ah, cnt in cx
  359. ourser4:clc                ; assume success
  360.     xchg    ah,al            ; put return status in ah
  361.     xor    al,al
  362.     cmp    ah,3            ; serious error status?
  363.     jb    ourserx            ; b = no, zero is success
  364.     stc                ; set carry too
  365. ourserx:mov    sp,kstack         ; move to caller's stack
  366.     and    tcpflag,not 1        ; say we are not running TCP
  367.     pop    bp
  368.     pop    bx
  369.     pop    dx
  370.     pop    si
  371.     pop    di
  372.     pop    es
  373.     pop    ds
  374.     ret                ; AX and CX are changed as returns
  375. ktcpcom endp
  376.  
  377. ; Copy contents of msgbuf (local Telnet msg collector buffer) to main body.
  378. oursmsg    proc    near
  379.     mov    cx,_msgcnt
  380.     jcxz    ourser3            ; z = no msgs
  381.     cmp    cx,_bapireq        ; longer than request?
  382.     jbe    oursmsg1        ; be = no
  383.     mov    cx,_bapireq        ; do this much now
  384. oursmsg1:push    cx
  385.     mov    si,offset DGROUP:_msgbuf ; whence it comes
  386.     mov    di,word ptr userbuf    ; where it goes
  387.     mov    ax,word ptr userbuf+2    ; segment
  388.     mov    es,ax
  389.     cld
  390.     rep    movsb            ; copy our buffer to theirs
  391.     pop    cx            ; return count in cx
  392.     mov    _bapiret,cx        ; return count to user
  393.     sub    _msgcnt,cx        ; deduct chars relayed
  394.     cmp    _msgcnt,0        ; examine remainder
  395.     je    oursmsg3        ; e = none
  396.     mov    ax,_msgcnt        ; count
  397.     push    ax
  398.     mov    ax,offset DGROUP:_msgbuf
  399.     push    ax            ; destination
  400.     add    ax,_msgcnt        ; source
  401.     push    ax
  402.     call    _bcopy            ; copy to beginning of buffer
  403.     add    sp,6            ; clean stack
  404. oursmsg3:mov    ax,0            ; return status of success
  405.     ret
  406. oursmsg    endp
  407.  
  408.  
  409. ; tcpaddress db    'unknown',(32-($-tcpaddress)) dup (0),0
  410. ; tcpsubnet  db    '255.255.255.0',(32-($-tcpsubnet)) dup (0),0
  411. ; tcpdomain  db    'unknown',(32-($-tcpdomain)) dup (0),0
  412. ; tcpgateway db    'unknown',(32-($-tcpgateway)) dup (0),0
  413. ; tcpprimens db    'unknown',(32-($-tcpprimens)) dup (0),0
  414. ; tcpsecondns db 'unknown',(32-($-tcpsecondns)) dup (0),0
  415. ; tcphost db    (60 -($-tcphost)) dup (0),0
  416. ; tcpbcast db    '255.255.255.255',(32-($-tcpbcast)) dup (0),0
  417. ; tcpport dw    23
  418. ; tcppdint dw    60h
  419. ; tcpdata dw    offset tcpaddress ; externally visible far pointers
  420. ;     dw    offset tcpsubnet
  421. ;     dw    offset tcpdomain
  422. ;     dw    offset tcpgateway
  423. ;     dw    offset tcpprimens
  424. ;     dw    offset tcpsecondns
  425. ;    dw    offset tcphost
  426. ;    dw    offset tcpbcast
  427. ;    dw    offset tcpport
  428. ;    dw    offset tcppdint
  429. ;    dw    offset tcpttbuf
  430.  
  431.     public    ktcpstart
  432. ktcpstart proc    far
  433.     ASSUME    DS:DATA, ES:DGROUP
  434.     push    es            ; save regs on main Kermit stack
  435.     push    ds
  436.     push    di
  437.     push    si
  438.     push    dx
  439.     push    cx
  440.     push    bx
  441.     push    bp
  442.     mov    ax,DGROUP
  443.     mov    es,ax            ; destination is the TCP module
  444.     cld
  445.     mov    tcpdata,bx        ; store offset of Kermit data block
  446.     mov    si,[bx]            ; get offset of our IP address
  447.     mov    di,offset DGROUP:_kmyip    ; our storage slot
  448.     mov    cx,16            ; max bytes
  449. start5:    lodsb
  450.     stosb
  451.     or    al,al
  452.     loopne    start5            ; copy IP address string, asciiz
  453.     xor    al,al            ; extra terminator
  454.     stosb
  455.     mov    si,[bx+2]        ; get offset in Kermit
  456.     mov    di,offset DGROUP:_knetmask
  457.     mov    cx,16
  458. start6:    lodsb
  459.     stosb
  460.     or    al,al
  461.     loopne    start6
  462.     xor    al,al
  463.     stosb
  464.     mov    si,[bx+4]            ; get offset in Kermit
  465.     mov    di,offset DGROUP:_kdomain
  466.     mov    cx,32
  467. start7:    lodsb
  468.     stosb
  469.     or    al,al
  470.     loopne    start7
  471.     xor    al,al
  472.     stosb
  473.     mov    si,[bx+6]            ; get offset in Kermit
  474.     mov    di,offset DGROUP:_kgateway
  475.     mov    cx,32
  476. start8:    lodsb
  477.     stosb
  478.     or    al,al
  479.     loopne    start8
  480.     xor    al,al
  481.     stosb
  482.     mov    si,[bx+8]            ; get offset in Kermit
  483.     mov    di,offset DGROUP:_kns1
  484.     mov    cx,32
  485. start9:    lodsb
  486.     stosb
  487.     or    al,al
  488.     loopne    start9
  489.     xor    al,al
  490.     stosb
  491.     mov    si,[bx+10]            ; get offset in Kermit
  492.     mov    di,offset DGROUP:_kns2
  493.     mov    cx,32
  494. start10:lodsb
  495.     stosb
  496.     or    al,al
  497.     loopne    start10
  498.     xor    al,al
  499.     stosb
  500.     mov    si,[bx+12]            ; get offset in Kermit
  501.     mov    di,offset DGROUP:_khost
  502.     mov    cx,60
  503. start11:lodsb
  504.     stosb
  505.     or    al,al
  506.     loopne    start11
  507.     xor    al,al
  508.     stosb
  509.     mov    si,[bx+14]            ; broadcast address
  510.     mov    di,offset DGROUP:_kbcast
  511.     mov    cx,32
  512. start12:lodsb
  513.     stosb
  514.     or    al,al
  515.     loopne    start12
  516.     xor    al,al
  517.     stosb
  518.     mov    si,[bx+16]        ; TCP port
  519.     mov    ax,[si]
  520.     mov    es:_kport,ax
  521.     mov    si,[bx+18]        ; Packet Driver Interrupt
  522.     mov    ax,[si]
  523.     mov    es:_kpdint,ax        ; 0 means scan
  524.     mov    si,[bx+20]        ; offset of term-type string
  525.     mov    di,offset DGROUP:_ktttype ; local storage of the string
  526.     mov    cx,32
  527. start13:lodsb
  528.     stosb
  529.     or    al,al
  530.     loopne    start13
  531.     xor    al,al
  532.     stosb
  533.  
  534.     mov    es:_display_mode,0    ; presume quiet screen
  535.     test    flags.remflg,dquiet    ; quiet display mode?
  536.     jnz    start14            ; nz = yes. Don't write to screen
  537.     inc    es:_display_mode    ; say can write to screen
  538. start14:mov    es:_kserver,0        ; assume not a server
  539.     test    flags.remflg,dserver    ; Server mode?
  540.     jz    start15            ; z = no
  541.     mov    es:_kserver,1        ; say being a server (do Listen)
  542. start15:mov    es:_kdebug,0        ; assume no debug mode
  543.     test    flags.debug,0ffh    ; debugging active?
  544.     jz    start16            ; z = no
  545.     inc    es:_kdebug        ; turn on debugging here
  546. start16:mov    ax,flags.vtflg        ; get terminal type index
  547.     mov    es:_kterm,ax
  548.     mov    al,crt_lins        ; get display height
  549.     mov    es:_kterm_lines,al
  550.     mov    al,crt_cols        ; get display width
  551.     mov    es:_kterm_cols,al
  552.  
  553. start20:mov    bx,tcptos        ; top of stack for tcp code
  554.  
  555.     assume    ds:DGROUP, ES:NOTHING
  556.     
  557.     mov    ax,dgroup        ; set addressibility to our dgroup
  558.     mov    ds,ax
  559.     mov    es,ax
  560.     mov    word ptr tcpstack+2,ax    ; set TCP stack seg
  561.     mov    word ptr kstack,sp    ; store Kermit's stack ptr
  562.     mov    sp,bx            ; new TCP stack pointer, DGROUP based
  563.     mov    bp,sp            ; preset this as insurance
  564.     or    tcpflag,1        ; say this is running TCP code
  565.     call    _main            ; call the C code
  566.     and    tcpflag,not 1        ; finished running tcp code
  567.     mov    sp,word ptr kstack    ; restore for Kermit's main stack
  568.     mov    bx,data            ; main Kermit data segment
  569.     mov    es,bx
  570.     mov    bx,tcpdata        ; pointer to storage word
  571.     mov    cx,_kpdint        ; report back Packet Driver Int
  572.     mov    bx,es:[bx+18]        ; get address of storage slot
  573.     mov    es:[bx],cx        ; store value in main data seg
  574.     pop    bp            ; restore regs, Kermit's main stack
  575.     pop    bx
  576.     pop    cx
  577.     pop    dx
  578.     pop    si
  579.     pop    di
  580.     pop    ds
  581.     pop    es
  582.     ret                ; return to caller
  583. ktcpstart endp
  584.  
  585.     public    ktcpstop
  586. ktcpstop proc    far
  587.     assume    ds:dgroup, es:nothing
  588.     push    es            ; save regs on the user's stack
  589.     push    ds
  590.     push    di
  591.     push    si
  592.     push    dx
  593.     push    cx
  594.     push    bx
  595.     push    bp
  596.     mov    ax,dgroup        ; set addressibility to our dgroup
  597.     mov    ds,ax
  598.     mov    kstack,sp        ; remember Kermit's main sp
  599.     or    tcpflag,1        ; say we are running TCP code
  600.     mov    ax,word ptr tcpstack    ; set sp to TCP sp
  601.     mov    sp,ax
  602.     mov    bp,sp            ; preset this as insurance
  603.     push    ds
  604.     pop    es
  605.     xor    ax,ax
  606.     push    ax            ; exit(0) setup
  607.     call    _exit
  608.     add    sp,2            ; returns status in AX
  609.     mov    tempax,ax
  610.     mov    ax,word ptr tcpstack    ; set sp to TCP sp again
  611.     mov    sp,ax
  612.     mov    bp,sp            ; preset this as insurance
  613.     call    _pkt_release        ; do this as insurance
  614.     mov    ax,tempax        ; regain status
  615.     push    ax
  616.     call    unhookvect        ; ditto
  617.     pop    ax
  618.     mov    tcpflag,0        ; no one is running the TCP code
  619.     mov    sp,kstack
  620.     pop    bp            ; restore regs, Kermit's main stack
  621.     pop    bx
  622.     pop    cx
  623.     pop    dx
  624.     pop    si
  625.     pop    di
  626.     pop    ds
  627.     pop    es
  628.     ret                ; return to caller
  629. ktcpstop endp
  630.  
  631.     public    _readback
  632. _readback proc    near
  633.     assume    ds:dgroup, es:dgroup
  634.     push    bp
  635.     mov    bp,sp
  636.     push    si
  637.     push    di
  638.     push    es
  639.     mov    ax,data
  640.     mov    es,ax
  641.     mov    si,offset dgroup:_kmyip
  642.     push    si
  643.     push    si
  644.     call    _strlen                ; get length of string
  645.     add    sp,2
  646.     pop    si
  647.     mov    di,tcpdata            ; copy to Kermit main body
  648.     mov    di,es:[di]            ; offset of the string
  649.     mov    cx,ax
  650.     cld
  651.     rep    movsb
  652.     xor    al,al
  653.     stosb                    ; terminator
  654.     mov    si,offset dgroup:_knetmask
  655.     mov    di,tcpdata
  656.     mov    di,es:[di+2]
  657.     mov    cx,17
  658.     rep    movsb
  659.     stosb                    ; terminator
  660.     mov    si,offset dgroup:_kgateway
  661.     mov    di,tcpdata
  662.     mov    di,es:[di+6]
  663.     mov    cx,17
  664.     rep    movsb
  665.     stosb                    ; terminator
  666.     mov    si,offset dgroup:_kns1
  667.     mov    di,tcpdata
  668.     mov    di,es:[di+8]
  669.     mov    cx,17
  670.     rep    movsb
  671.     stosb                    ; terminator
  672.     mov    si,offset dgroup:_kns2
  673.     mov    di,tcpdata
  674.     mov    di,es:[di+10]
  675.     mov    cx,17
  676.     rep    movsb
  677.     stosb                    ; terminator
  678.     pop    es
  679.     pop    si
  680.     pop    di
  681.     pop    bp
  682.     ret
  683. _readback endp
  684.  
  685. ; Track Telnet echo variable (0 do not do local echo) into terminal emulator
  686. ; and Kermit main body. Call this each time Telnet options change echo.
  687.     public    _kecho
  688. _kecho    proc    near
  689.     assume    ds:data, es:dgroup
  690.     push    bp
  691.     mov    bp,sp
  692.     push    ds
  693.     push    es
  694.     push    si
  695.     push    ax
  696.     mov    ax,data            ; Kermit main data segment
  697.     mov    ds,ax
  698.     mov    ax,dgroup
  699.     mov    es,ax
  700.     mov    ax,[bp+4+0]        ; get Telnet _echo variable
  701.     and    yflags,not lclecho    ; assume no local echo in emulator
  702.     or    al,al            ; Telnet local echo is off?
  703.     jz    kecho1            ; z = yes
  704.     mov    al,lclecho        ; lclecho flag for emulator
  705. kecho1:    or    yflags,al        ; set terminal emulator
  706.     mov    si,portval
  707.     mov    [si].ecoflg,al        ; set mainline SET echo flag
  708.     cmp    ttyact,0        ; acting as a Terminal?
  709.     je    kecho2            ; e = no
  710. ;[HF]    call    dword ptr ftogmod    ; toggle mode line
  711. ;[HF]    call    dword ptr ftogmod    ; and again
  712. kecho2:    pop    ax
  713.     pop    si
  714.     pop    es
  715.     pop    ds
  716.     pop    bp
  717.     ret
  718. _kecho    endp
  719. _TEXT    ends
  720.         end
  721.  
  722.