DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T m

⟦b87ce8078⟧ TextFile

    Length: 129973 (0x1fbb5)
    Types: TextFile
    Names: »mssset.asm«

Derivation

└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
    └─⟦71044c191⟧ »EurOpenD3/misc/kermit.ms-2.32.tar.Z« 
        └─⟦31f2d420d⟧ 
            └─⟦this⟧ »mssset.asm« 

TextFile

        NAME    mssset
; File MSSSET.ASM
; Set command module
; edit history:
; Last edit 3 Dec 1988
; 3 Dec 1988 Add ASSIGN command. Same as DEFINE except substitution variables
;  are expanded in the definition string, thus making a copy command.
; 21 Nov 1988 Version 2.32
; 20 Nov 1988 Let \%number items on DO MACRO arg1 arg2 ... accept curly braced
;  strings as individual "words."
; 12 Nov 1988 Check table space before opening a new Take file.
; 1 Nov 1988 Add SET SERVER TIMEOUT command.
; 5 Oct 1988 Remove script details from main STATUS display.
; 27 August 1988 Add dtrans.ebquot to retain default 8-bit quoting condition.
; 28 July 1988 Add ASK command.
; 17 July 1988 Correct Show Server status getsflg and add HOST to DISABLE
;  help message. Tnx to Terry Kennedy. [jrd]
; 1 July 1988 Version 2.31
; 15 May 1988 Add global status kstatus
; 8 April 1988 Move Take disk file buffers to Macro definition buffer and
;  name such Takes "<null>Tn" (n='1' to 'maxtak'). [jrd]
; 26 March 1988 Add global buffer subbuf and byte comand.cmper to permit
;  '\%x' style string substitution in commands. [jrd]
;  Comand.cmper non-zero allows phrase '\%n' to be read as a literal. [jrd]
; 20 March 1988 Add expanded Show command, allow macro name in Show Mac. [jrd]
; 9 Feb 1988 Add mode line status of on (owned by host). [jrd]
; 1 Jan 1988 version 2.30

        public setcom, status, baudprt, prmptr, dodef, stat0, statc
        public setcpt, docom, shomac, dmpname, stkadr
        public setrx, shorx, rxtable, shcom, shlog, shpro, shterm, shscpt
        public shfile, srvdsa, srvena, srchkw, srchkb, shserv
        public mcctab, takopen, takclos, ask, assign
        include mssdef.h

braceop equ     7bh                     ; opening curly brace
bracecl equ     7dh                     ; closing curly brace
macmax  equ     50              ; max # of macros
maketab MACRO                   ; Assembler Macro to make rxtable [jrd]
cnt = 0
        rept 256
        db      cnt             ; initialize table to 0 .. 255
cnt = cnt + 1
        endm
        db      0               ; table off (0) or on (1) indicator
ENDM
datas   segment public 'datas'
        extrn   comand:byte, intake:byte, flags:byte, trans:byte
        extrn   takadr:word, taklev:byte, inichk:byte, portval:word
        extrn   curdsk:byte, setktab:byte, setkhlp:byte, dtrans:byte
        extrn   spause:byte, filtst:byte, maxtry:byte, imxtry:byte
        extrn   script:byte, denyflg:word, comptab:byte, termtb:byte
        extrn   sloghnd:word, ploghnd:word, tloghnd:word, decbuf:byte
        extrn   kstatus:word, errlev:byte, alrhms:byte, srvtmo:byte

kerm    db      'Kermit-MS>$'
crlf    db       cr,lf,'$'
crlfsp  db      cr,lf,' ',' ','$'       ; crlf space space
eqs     db      ' = $'
spaces  db      '    $'
prmptr  dw      kerm                    ; pointer to prompt
prm     db      60 dup (?)              ; Buffer for new prompt
rdbuf   db      255 dup (?)             ; work space; room for macro def
                                        ;  and for Status display line
tempptr dw      0                       ; pointer into work buffer
domacptr dw     0                       ; pointer to DO MAC string

min     dw      0
max     dw      0
numerr  dw      0
numhlp  dw      0
stflg   db      0               ; Says if setting SEND or RECEIVE parameter
temp    dw      0
temp1   dw      0                       ; Temporary storage
temp2   dw      0                       ; Temporary storage
deftemp dw      0
shmcnt  dw      0

stent   struc                   ; structure for status information table sttab
sttyp   dw      ?               ; type (actually routine to call)
msg     dw      ?               ; message to print
val2    dw      ?               ; needed value: another message, or tbl addr
tstcel  dw      ?               ; address of cell to test, in data segment
basval  dw      0               ; base value, if non-zero
stent   ends
;;;;; Additional datas segment material is at the end of this file, to assist
;;;;; MASM 4 with out of symbol table space problems.
datas   ends

code    segment public 'code'
        extrn prserr:near, comnd:near, dobaud:near, cmblnk:near, locate:near
        extrn prompt:near, coms:near, defkey:near, cwdir:near
        extrn prtscr:near, getbaud:near, isfile:near, strlen:near
        extrn strcpy:near, cnvlin:near, katoi:near, decout:near
        extrn vts:near, vtstat:near, shomodem:near, setalrm:near

        assume  cs:code, ds:datas, es:nothing

; DO defined macro command
; DO macname variable variable   also defines variables \%1, \%2, ...\%9
DOCOM   PROC    NEAR
        mov     dx,offset mcctab        ; table of macro defs
        mov     bx,0                    ; help is table
        mov     ah,cmkey                ; get key word (macro name)
        call    comnd                   ; get pointer to keyword structure
         ret
         nop
         nop
        mov     comand.cmquiet,0        ; permit command echoing
        mov     domacptr,bx             ; address of definition string
; note: remtab updates domacptr because substitutions many modify the table
        mov     bx,offset decbuf        ; point to borrowed work buffer
        mov     word ptr[bx],0          ; clear buffer
        mov     dx,offset dohlp         ; help
        mov     comand.cmblen,length rdbuf ; length of analysis buffer
        mov     ah,cmtxt                ; get line of text, if any
        call    comnd
         ret
         nop
         nop
        mov     al,ah
        mov     ah,0
        mov     deftemp,ax              ; save byte count of command args
        cmp     al,0                    ; anything given?
        je      docom9                  ; e = no, just do the macro
        mov     word ptr rdbuf+3,' 1'   ; number of first variable
docom8: mov     rdbuf,0                 ; clear length field, install \%x name
        mov     word ptr rdbuf+1,'%\'   ; start with '\%1 '
        mov     word ptr rdbuf+5,0      ; clear text field
        mov     tempptr,offset rdbuf+5  ; pointer to location of found word
        mov     ch,0                    ; make cx = 1 - 9
        mov     cl,rdbuf+3              ; cx = word # of interest, for getwrd
        sub     cl,'0'                  ; remove ascii bias
        mov     si,offset decbuf        ; source = work buffer (borrowed)
        call    getwrd                  ; get CX-th word from  work buf (1-9)
        cmp     deftemp,0               ; length of word, was it found?
        je      docom9                  ; e = no, end variable definition part
        add     deftemp,4               ; count '\%n ' in command line length
        call    dodecom                 ; add keyword+def using DEF MAC below
         nop
         nop
         nop
        inc     rdbuf+3                 ; inc number of variable in '\%n '
        cmp     rdbuf+3,'9'
        jbe     docom8                  ; do '1' through '9', if available

                                        ; DO the macro itself
docom9: cmp     taklev,maxtak           ; room in take level?
        jl      docom2                  ; l = yes, continue
        mov     dx,offset ermes4        ; else complain
        jmp     reterr
docom2: inc     taklev                  ; increment take level
        add     takadr,size takinfo
        mov     bx,takadr               ; point to current buffer
        mov     si,domacptr             ; address of macro definition string
        mov     [bx].takbuf,si          ; remember in Take structure
        mov     cl,[si]                 ; length of definition
        mov     ch,0
        inc     si                      ; point to actual definition
        mov     [bx].taktyp,0ffh        ; flag as a macro
        mov     [bx].takptr,si          ; point to beginning of def
        mov     [bx].takcnt,cx          ; # of chars in buffer
        jmp     rskp
DOCOM   ENDP

; Extract CX-th word (cx = 1-9) from buffer (DI). Enter with si = source
; string and tempptr pointing at destination. Returns deftemp (count) of
; transferred characters. Allow string in curly braces to exist as a word.
; Adjacent curly braced strings are separate "words":
;    {this is word-one}{this is word-two}word-three.
; All registers preserved.
getwrd  proc    near
        push    ax
        push    cx
        push    dx
        push    si
        push    di
        push    es
        push    ds
        pop     es                      ; set es to datas segment
getwr1: push    cx                      ; save word counter (1-9)
        mov     deftemp,0               ; no bytes transferred yet
        mov     di,tempptr              ; where to store word/string
        mov     byte ptr [di],0         ; clear destination
        mov     dx,si                   ; start looking here in work buf
        call    strlen                  ; cx = remaining length of work buf
        jcxz    getwr6                  ; z = nothing there, quit
getwr2: lodsb
        cmp     al,' '                  ; skip leading whitespace
        loope   getwr2
        dec     si                      ; return to break char
                                        ; Parse curly brace delimited string
                                        ; end with si after closing brace
        mov     dl,0                    ; assume "opening brace" is a null
        mov     dh,' '                  ; assume "closing brace" is a space
        mov     cx,1                    ; we are at brace level 1
        cmp     byte ptr [si],braceop   ; starting with a real opening brace?
        jne     getwr3                  ; ne = no
        inc     si                      ; skip opening brace
        mov     dl,braceop              ; opening brace (we count them up)
        mov     dh,bracecl              ; closing brace (we count them down)
getwr3: cld                             ; search forward
        lodsb                           ; read a char
        stosb                           ; store in output buffer
        cmp     al,0                    ; at end of text?
        jne     getwr3a                 ; ne = no
        dec     si                      ; stay at null terminator
        dec     di
        jmp     short getwr6            ; we are done with this "word"
getwr3a:inc     deftemp                 ; count copied char
        cmp     al,dl                   ; an opening brace?
        jne     getwr4                  ; ne = no
        inc     cx                      ; yes, increment brace level
        jmp     short getwr3            ;  and continue scanning

getwr4: cmp     al,dh                   ; closing brace?
        jne     getwr3                  ; ne = no, continue scanning
        dec     cx                      ; yes, decrement brace level
        cmp     byte ptr [si],0         ; have we just read the last char?
        jne     getwr5                  ; no, continue scanning
        mov     cx,0                    ; yes, this is the closing brace
getwr5: cmp     cx,0                    ; at level 0?
        jne     getwr3                  ; ne = no, #opening <> #closing braces
        mov     byte ptr [di-1],0       ; plant terminator on closing brace
        dec     deftemp                 ; do not count closing brace

getwr6: pop     cx                      ; recover word counter
        mov     byte ptr [di],0
        jcxz    getwrx                  ; just in case
        loop    getwr1                  ; do until desired word is copied
getwrx: pop     es
        pop     di
        pop     si
        pop     dx
        pop     cx
        pop     ax
        ret
getwrd  endp

; DEFINE and ASSIGN macro commands
; Data structures comments. Macro name is stored in table mcctab as if we
; had used macro mkeyw, such as       mkeyw 'mymac',offset my_definition.
; In detail:    db      length of name
;               db      'name'
;               db      '$'
;               dw      offset of definition string
; Mcctab begins with a byte holding the number of macros in the table; one,
;  IBM, is established at assembly time. Mcctab is 10*macmax bytes long.
; Pointer mccptr holds the offset of the next free byte in mcctab.
; Definition strings are stored in table macbuf as
;               db      length of definition string below
;               db      'definition string'
; Pointer macptr holds the offset of the next free byte in macbuf. Macbuf
; is nominally 100*macmax bytes long.
; A new definition is read into buffer rdbuf+1, where byte rdbuf is reserved
;  to hold the length of the macro's name during intermediate processing.
; If the definition is absent then the macro is removed from the tables.
; Rewritten 13 June 1987 [jrd]
;
; ASSIGN is equivalent to DEFINE, except in the definition string substitution
; variable names are expanded to their definitions. This becomes a copy cmd.
; DEFINE does not expand substitution variables.

ASSIGN  PROC    NEAR
        mov     temp,0                  ; flag command as ASSIGN, vs DEFINE
        jmp     dodefcom                ; common code
ASSIGN  ENDP

DODEF   PROC    NEAR
        mov     temp,1                  ; flag command as DEFINE, vs ASSIGN
DODEFCOM:
        mov     comand.cmper,1          ; do not react to '\%' in macro name
        mov     ah,cmfile
        mov     dx,offset rdbuf+1       ; buffer for macro name
        mov     word ptr rdbuf,0
        mov     bx,offset macmsg
        call    comnd                   ; get macro name
         ret
         nop
         nop
        cmp     ah,0                    ; null entry?
        jne     dodef1                  ; ne = no
        mov     dx,offset ermes6        ; more parameters needed
        jmp     reterr

dodef1: mov     bx,dx                   ; updated pointer
        mov     byte ptr [bx-1],' '     ; replace null with space separator
        mov     word ptr [bx],0         ; terminator, in case no command
        mov     ax,temp                 ; get ASSIGN/DEFINE flag
        mov     comand.cmper,al         ; react (DEF) to '\%' in definition
        mov     ah,cmtxt                ; get a line of text
        mov     dx,offset macmsg
        mov     comand.cmblen,length rdbuf ; our buffer length
        sub     comand.cmblen,al        ; minus part used
        dec     comand.cmblen           ; space separator
        call    comnd                   ; get macro name
         ret
         nop
         nop
        sub     bx,offset rdbuf         ; length of command line
        dec     bx                      ; minus count byte
        mov     deftemp,bx              ; save length of command line
;;      jmp     dodecom                 ; common code below
DODEF   ENDP
                                        ; DODECOM called by DO mac above
; accepts rdbuf+1 et seq = <macro name><spaces><arg><spaces><arg> ...
; byte rdbuf computed here as length of keyword
DODECOM PROC    NEAR
        push    si                      ; macro name in rdbuf+1 et seq
        push    di                      ; cmd line length in deftemp
        push    es
        push    ds                      ; address data segment
        pop     es
        mov     cx,deftemp              ; cmd line len, cx = running counter
        mov     rdbuf,0                 ; number of chars in keyword so far
                                        ; uppercase the keyword, look for end
        mov     si,offset rdbuf+1       ; point at macro name text
        cld                             ; strings go forward
dode2:  lodsb                           ; get a byte, dec cx
        cmp     al,'a'                  ; map lower case to upper
        jb      dode3
        cmp     al,'z'
        ja      dode3
        sub     al,'a'-'A'
        mov     [si-1],al               ; uppercase if necessary
dode3:  inc     rdbuf                   ; increment char count of keyword
        cmp     al,' '                  ; is this the break character?
        loopne  dode2                   ; no, loop thru rest of word
        jne     dode4                   ; ne = did not end with break char
        dec     rdbuf                   ; yes, don't count in length
dode4:  push    di
        mov     di,offset rdbuf         ; point at mac name length byte
        call    remtab                  ; remove any duplicate keyword
        pop     di
        jcxz    dode6                   ; cx = 0 means no keyword
                                ; check for free space for keyword and string
        mov     al,rdbuf                ; keyword text length
        add     al,4                    ; plus overhead bytes
        xor     ah,ah
        add     ax,mccptr               ; add to free space pointer
        cmp     ax,offset mcctab+mcclen ; enough room for name?
        jb      dode5                   ; b = yes
        mov     dx,offset ermes1        ; too many macro names
        pop     es
        pop     di
        pop     si
        jmp     reterr
dode5:
        mov     di,si                   ; si = source address
        add     di,cx                   ; length of string
        dec     di                      ; omit null terminator
        std
        mov     al,' '                  ; scan off trailing spaces
        repe    scasb
        add     di,2                    ; backup to terminator slot
        cld
        mov     byte ptr [di],0         ; plant new terminator
        mov     dx,si
        call    strlen                  ; get new length into cx

        mov     di,si                   ; scan after keyword name
        mov     al,' '                  ; remove leading spaces in string
        repe    scasb
        je      dode6                   ; e = all spaces
        inc     cx                      ; offset auto decrement of rep
        dec     di                      ; offset auto increment of rep

        mov     si,di                   ; point to start of string text
        mov     dx,di                   ; source of definition text
        call    strlen                  ; get length of string into cx
        mov     ax,cx                   ; length of string
        mov     deftemp,cx              ; remember it here
        inc     ax                      ; plus its count byte
        add     ax,macptr               ; plus free space pointer
        cmp     ax,offset macbuf+maclen ; enough room for definition string?
        jb      dode7                   ; b = yes
        pop     es
        pop     di
        pop     si
        mov     dx,offset ermes2        ; no room for definition
        jmp     reterr
dode6:  pop     es
        pop     di
        pop     si
        jmp     rskp
                                        ; install new keyword in mcctab
dode7:  cmp     deftemp,0               ; deftemp = length of definition
        je      dode10                  ; e = no def, exit now
        mov     bx,offset mcctab
        mov     dx,offset rdbuf         ; count byte + name string
        call    addtab
                        ; copy definition into buffer, changing commas to CRs
        mov     di,macptr               ; free space in string buffer
        mov     cx,deftemp              ; length of definition string
        mov     byte ptr[di],cl         ; store length of string
        inc     di                      ; skip over count byte
dode8:  lodsb                           ; get a byte
        cmp     al,','                  ; comma?
        jne     dode9                   ; no, keep going
        mov     al,cr                   ; else replace with cr
dode9:  stosb
        loop    dode8                   ; keep copying
        mov     macptr,di               ; update free ptr
dode10: pop     es
        pop     di
        pop     si
        jmp     rskp
DODECOM ENDP

; ASK <variable or macro name> <prompt string>
; Defines indicated variable/macro with text from user at keyboard or pipe
; (but not from a Take/macro). Prompt string is required.       [jrd]
ASK     PROC    NEAR
        mov     dx,offset rdbuf+1       ; point to work buffer
        mov     word ptr rdbuf,0
        mov     bx,offset askhlp1       ; help
        mov     comand.cmper,1          ; do not expand variable name
        mov     ah,cmfile               ; get variable name
        call    comnd
         jmp    r
         nop
        cmp     ah,0                    ; anything given?
        jne     ask2                    ; ne = yes
        mov     dx,offset ermes6        ; more parameters needed
        jmp     reterr

ask2:   xchg    ah,al
        mov     ah,0
        mov     bx,offset rdbuf+1       ; start of name
        add     bx,ax                   ; plus length of variable name
        mov     byte ptr [bx],' '       ; put space separator after name
        inc     ax                      ; count space
        mov     temp,ax                 ; remember length here
                                        ; get ASK command prompt string
        inc     bx                      ; put prompt string here
        mov     byte ptr [bx],0         ; safety terminator
        mov     dx,offset askhlp2
        mov     comand.cmblen,127       ; our buffer length
        sub     comand.cmblen,al        ;  minus part used above
        mov     ah,cmtxt                ; get prompt string
        call    comnd
         jmp    r
         nop
        cmp     ah,0                    ; anything given?
        jne     ask4                    ; ne = yes
        mov     dx,offset ermes6        ; more parameters needed
        jmp     reterr

ask4:   mov     ax,takadr               ; we could be in a macro or Take file
        mov     temp2,ax                ; save Take address
        mov     al,taklev
        mov     ah,0
        mov     temp1,ax                ; and Take level
        mov     dx,size takinfo         ; bytes for each current Take
        mul     dx                      ; times number of active Take/macros
        sub     takadr,ax               ; clear Take address as if no
        mov     taklev,0                ;  Take/macro were active so that
                                        ;  user input is from kbd or pipe
        mov     word ptr [bx],'$ '      ; printing terminator for prompt
        mov     dx,offset rdbuf+1
        add     dx,temp                 ; prompt for input string
        call    prompt                  ; buf = <var name>< ><prompt string>
        mov     bx,offset rdbuf+129     ; use this buffer for raw user input
        mov     word ptr [bx],0         ; insert terminator
        mov     dx,offset askhlp3       ; help for user input
        mov     ah,cmtxt                ; read user's input string
        call    comnd
         jmp    ask9                    ; exit now on ^C from user
         nop
        mov     cl,ah                   ; length of entry
        mov     ch,0
        jcxz    ask8                    ; z = empty
        mov     si,offset rdbuf+129     ; source string
        mov     di,offset rdbuf+1       ; start of variable name
        add     di,temp                 ; di points to final user string
        push    es                      ; save es
        push    ds
        pop     es                      ; set es to datas segment
        cld
ask6:   lodsb                           ; read original user string char
        cmp     al,','                  ; literal comma?
        jne     ask7                    ; ne = no
        mov     ax,'{\'                 ; yes. Replace literal comma
        stosw                           ;  with numerical equivalent \{44}
        mov     ax,'44'                 ;  to permit commas in macro def
        stosw
        add     temp,4
        mov     al,'}'
ask7:   stosb                           ; store string character
        inc     temp                    ; length of <variable>< ><user string>
        loop    ask6
        pop     es
ask8:   mov     ax,temp                 ; length of <variable>< ><user string>
        mov     deftemp,ax              ; put here for dodecom usage
        mov     ax,temp2
        mov     takadr,ax               ; restore Take address
        mov     ax,temp1
        mov     taklev,al               ; restore Take level
        jmp     DODECOM                 ; define the macro/variable and exit

ask9:   mov     ax,temp2                ; failure path
        mov     takadr,ax               ; restore Take address
        mov     ax,temp1
        mov     taklev,al               ; restore Take level
        ret                             ; return command failure
ASK     ENDP

; Open a disk based Take file buffer. Define macro named "<null>T<'taklev'>",
; allocate 128 byte uninitiated buffer in mcctab for disk i/o. Leading null
; is to prevent user from employing the same name accidentally. Return offset
; of buffer in [takadr].takbuf and set [takadr].takptr pointing to it.
; Return carry clear for success, carry set for failure.

TAKOPEN PROC    NEAR
        push    ax
        push    bx
        push    dx
        push    di
        mov     dx,offset ermes2        ; says no room for defintions
        mov     ax,dmasiz+1             ; count byte plus length of buffer
        add     ax,macptr               ; plus free space pointer
        cmp     ax,offset macbuf+maclen ; enough room for definition string?
        jae     takopen1                ; ae = no, complain
        cmp     taklev,maxtak           ; room in take level?
        jl      takopen2                ; l = yes, continue
        mov     dx,offset ermes4        ; say too many Take files
takopen1:mov    ah,prstr
        int     dos
        pop     di
        pop     dx
        pop     bx
        pop     ax
        stc                             ; set carry for failure
        ret

takopen2:inc    taklev                  ; next Take
        add     takadr,size takinfo     ; pointer to Take structure
        mov     rdbuf,3                 ; length of name, 3 bytes <null>Tn
        mov     rdbuf+1,0
        mov     rdbuf+2,'T'             ; name of <null>Tn
        mov     al,taklev               ; Take level digit
        add     al,'0'                  ; add ascii bias
        mov     rdbuf+3,al              ; last of the name
        mov     di,offset rdbuf         ; pointer for remtab
        call    remtab                  ; remove possible old macro
        mov     bx,offset mcctab        ; table to use
        mov     dx,offset rdbuf         ; count and mac name to enter
        call    addtab                  ; returns string pointer in macptr
        mov     di,macptr
        add     macptr,dmasiz+1         ; set new free byte into pointer
        mov     byte ptr [di],dmasiz    ; string length (128 bytes)
        mov     bx,takadr               ; pointer to Take structure
        mov     [bx].takbuf,di          ; offset of Take buffer
        inc     di                      ; skip count byte in takbuf
        mov     [bx].takptr,di          ; init pointer to definition itself
        pop     di
        pop     dx
        pop     bx
        pop     ax
        clc                             ; carry clear for success
        ret
TAKOPEN ENDP

; Close Take file. Enter at Take level to be closed. Removes pseudo macro
; name <null>Tn and its buffer, closes disk file, pops Take level.

TAKCLOS PROC    NEAR
        cmp     taklev,0                ; anything to close?
        jle     takclo2                 ; le = no
        push    ax
        push    bx
        mov     bx,takadr               ; point to Take structure
        cmp     [bx].taktyp,0feh        ; disk file (vs macro)?
        jne     takclo1                 ; ne = no, no buffer to deallocate
        mov     rdbuf,3                 ; length of name
        mov     rdbuf+1,0
        mov     rdbuf+2,'T'             ; name of <null>Tn
        mov     al,taklev               ; Take level digit
        add     al,'0'                  ; add ascii bias
        mov     rdbuf+3,al              ; last of the name
        push    di
        mov     di,offset rdbuf         ; pointer for remtab
        call    remtab                  ; remove possible old macro
        pop     di
        mov     bx,[bx].takhnd          ; get file handle
        mov     ah,close2               ; close file
        int     dos
                                        ; both disk and macro Takes
takclo1:dec     taklev                  ; pop Take level
        mov     ah,taklev               ; get current Take level
        mov     intake,ah               ; remember here for later callers
        sub     takadr,size takinfo     ; get previous Take's address
        pop     bx
        pop     ax
takclo2:ret
TAKCLOS ENDP

; add an entry to a keyword table
; enter with bx = table address, dx = ptr to new entry, macptr = string offset,
; mccptr = offset of free bytes in table mcctab.
; no check is made to see if the entry fits in the table.
addtab  proc    near
        push    cx
        push    si
        push    es
        cld
        mov     ax,ds
        mov     es,ax           ; address data segment
        mov     bp,bx           ; remember where tbl starts
        mov     cl,[bx]         ; pick up length of table
        mov     ch,0
        inc     bx              ; point to actual table
        jcxz    addta4          ; cx = 0 if table is presently empty

addta1: push    cx              ; preserve count
        mov     si,dx           ; point to entry
        lodsb                   ; get length of new entry
        mov     cl,[bx]         ; and length of table entry
        mov     ah,0            ; assume they're the same size
        cmp     al,cl           ; are they the same?
        lahf                    ; remember result of comparison
        jae     addta2          ; is new smaller? no, use table length
        mov     cl,al           ; else use length of new entry
addta2: mov     ch,0
        lea     di,[bx+1]       ; point to actual keyword
        repe    cmpsb           ; compare strings
        pop     cx              ; restore count
        jb      addta4          ; below, insert before this one
        jne     addta3          ; not below or same, keep going
        sahf                    ; same. get back result of length comparison
        jb      addta4          ; if new len is smaller, insert here
        jne     addta3          ; if not same size, keep going
        mov     si,bx           ; else this is where entry goes
        jmp     short addta6    ; no insertion required
addta3: mov     al,[bx]
        mov     ah,0
        add     bx,ax           ; skip this entry
        add     bx,4            ; len + $ + value
        loop    addta1          ; and keep looking
addta4: mov     si,bx           ; this is first location to move
        mov     di,bx
        inc     ds:byte ptr [bp] ; remember we're adding one
        jcxz    addta6          ; no more entries, forget this stuff
        mov     bh,0            ; this stays 0
addta5: mov     bl,[di]         ; get length
        lea     di,[bx+di+4]    ; end is origin + length + 4 for len, $, value
        loop    addta5          ; loop thru remaining keywords
        mov     cx,di
        sub     cx,si           ; compute # of bytes to move
        push    si              ; preserve loc for new entry
        mov     si,di           ; first to move is last
        dec     si              ; minus one
        mov     di,dx           ; new entry
        mov     bl,[di]         ; get length
        lea     di,[bx+si+4]    ; dest is source + length of new + 4
        std                     ; move backward
        rep     movsb           ; move the table down (compress it)
        cld                     ; put flag back
        pop     si
addta6: mov     di,si           ; this is where new entry goes
        mov     si,dx           ; this is where it comes from
        mov     cl,[si]         ; length
        mov     ch,0
        add     cx,1            ; include count byte
        add     mccptr,cx       ; update free space pointer: cnt+name
        add     mccptr,3        ; plus '$' and pointer to string
        rep     movsb           ; stick it in
        mov     al,'$'          ; add printing terminator
        stosb
        mov     ax,macptr       ; and string offset
        stosw
        pop     es
        pop     si
        pop     cx
        ret
addtab  endp

; If new keyword matches an existing one then remove existing keyword,
; its string definition, compress tables mcctab and macbuf, readjust string
; pointers for each macro name, reduce number of macro table entries by one.
; DO MAC pointer (domacptr) is adjusted to follow deletion.
; Enter with DI pointing at length byte of mac name (followed by mac name).
; Otherwise, exit with no changes.  13 June 1987 [jrd]
remtab  proc    near
        push    ax
        push    bx
        push    cx
        push    si
        push    di
        mov     bx,offset mcctab+1      ; table of macro keywords
        mov     temp,0                  ; temp = current keyword
        cmp     byte ptr mcctab,0       ; any macros defined?
        jne     remta1                  ; ne = yes
        jmp     remtax                  ; else exit now
remta1:                                 ; match table keyword and text word
        mov     si,di                   ; pointer to user's cnt+name
        mov     cl,[si]                 ; length of user's macro name
        xor     ch,ch
        inc     si                      ; point to new macro name
        cmp     cl,[bx]                 ; compare length vs table keyword
        jne     remta4                  ; ne = not equal lengths, try another
        push    si                      ; lengths match, how about spelling?
        push    bx
        inc     bx                      ; point at start of keyword
remta2: mov     ah,[bx]                 ; keyword char
        mov     al,[si]                 ; new text char
        cmp     al,ah                   ; test characters
        jne     remta3                  ; ne = no match
        inc     si                      ; move to next char
        inc     bx
        loop    remta2                  ; loop through entire length
remta3: pop     bx
        pop     si
        jcxz    remta6                  ; z: cx = 0, exit with match;
                                        ;  else select next keyword
remta4: inc     temp                    ; number of keyword to test next
        mov     cx,temp
        cmp     cl,mcctab               ; all done? Recall, temp starts at 0
        jb      remta5                  ; b = not yet
        jmp     remtax                  ; exhausted search, unsuccessfully
remta5: mov     al,[bx]                 ; cnt (keyword length from macro)
        xor     ah,ah
        add     ax,4                    ; skip over '$' and two byte value
        add     bx,ax                   ; bx = start of next keyword slot
        jmp     remta1                  ; do another comparison
                                        ; new name already present as a macro
remta6: cld                             ; clear macro string and macro name
        push    ds
        pop     es                      ; set es to datas segment
        mov     temp,bx                 ; save ptr to found keyword
        mov     al,[bx]                 ; cnt (keyword length of macro)
        xor     ah,ah
        add     ax,2                    ; skip cnt and '$'
        add     bx,ax                   ; point to string offset field
        add     ax,2                    ; count offset field bytes
        sub     mccptr,ax               ; readjust free space ptr for names
        push    bx
        mov     bx,[bx]
        mov     temp1,bx                ; temp1 = offset of old string
        mov     al,[bx]                 ; length of old string
        xor     ah,ah
        inc     ax                      ; plus its count byte
        mov     temp2,ax                ; save here
        pop     bx
                                        ; clear keyword table mcctab
        add     bx,2                    ; compute source = next keyword
        mov     si,bx                   ; address of next keyword
        mov     di,temp                 ; address of found keyword
        mov     cx,offset mcctab+mcclen ; address of buffer end
        sub     cx,si                   ; amount to move
        jcxz    remtax                  ; cx = 0 means none
        rep     movsb                   ; move down keywords (deletes current)
                                        ; revise other string offsets
        mov     si,offset mcctab        ; table of string offsets
        inc     si                      ; skip count byte
        mov     cl,mcctab               ; current number of table entries
        xor     ch,ch
        dec     mcctab                  ; one less keyword
        mov     dx,temp1                ; address of old string
remta7: mov     al,[si]                 ; cnt of first keyword
        add     al,2                    ; plus cnt and '$'
        xor     ah,ah
        add     si,ax                   ; look at string offset
        cmp     dx,[si]                 ; old address vs this string
        ja      remta8                  ; a = address not affected
        mov     ax,temp2                ; size of old string
        sub     [si],ax                 ; adjust offset downward
remta8: add     si,2                    ; point to next table entry
        loop    remta7
        cmp     dx,domacptr             ; DO <macro> definition affected?
        ja      remta8a                 ; a = no (occurs before removal)
        mov     ax,temp2                ; get length being removed from table
        sub     domacptr,ax             ; revise pointer downward also
remta8a:mov     cl,taklev               ; consider all Take files
        mov     ch,0
        jcxz    remta9                  ; z = no active Take file
                                        ; revise Take file def pointers
        mov     bx,takadr               ; Take structure
remta8b:mov     ax,[bx].takbuf          ; pointer to definition
        cmp     dx,ax                   ; is this structure affected?
        ja      remta8d                 ; a = no
        mov     ax,temp2                ; length being removed from table
        sub     [bx].takbuf,ax          ; adjust string structure downward
        sub     [bx].takptr,ax          ; ditto for active read pointer
remta8d:sub     bx,size takinfo         ; preceeding Take file
        loop    remta8b
                                        ; remove old string
remta9: mov     di,temp1                ; address of old string = destination
        mov     ax,temp2                ; size of old string field
        mov     si,di
        add     si,ax                   ; plus length: source = next string
        sub     macptr,ax               ; readjust top of buf free string ptr
        mov     cx,offset macbuf+maclen ; end of buffer
        sub     cx,si                   ; number of bytes to move
        jcxz    remtax                  ; cx = 0 means none
        rep     movsb                   ; move old strings (garbage collect)
remtax: pop     di
        pop     si
        pop     cx
        pop     bx
        pop     ax
        ret
remtab  endp

; Common Get keyword + Get Confirm sequence. Call with dx = keyword table,
; bx = help message offset. Returns result in BX. Modifies AX, BX and temp.
; Returns rskp if sucessful or ret if failure. Used in many places below.
keyend  proc    near
        mov     ah,cmkey
        call    comnd
         ret
         nop
         nop
        mov     temp,bx
        mov     ah,cmcfm
        call    comnd
         ret
         nop
         nop
        mov     bx,temp
        jmp     rskp
keyend  endp

srvdsa  proc    near                    ; DISABLE Server commands
        mov     dx,offset srvdetab
        mov     bx,offset sdshlp
        call    keyend
         ret
         nop
         nop
        or      denyflg,bx              ; turn on bit (deny) for that item
        jmp     rskp                    ; return successfully
srvdsa  endp

srvena  proc    near                    ; ENABLE Server commands
        mov     dx,offset srvdetab      ; keyword table
        mov     bx,offset sdshlp        ; help on keywords
        call    keyend
         ret
         nop
         nop
        not     bx                      ; invert bits
        and     denyflg,bx              ; turn off (enable) selected item
        jmp     rskp
srvena  endp


; This is the SET command
; Called analyzers return rskp for success, else ret for failure
SETCOM  PROC    NEAR                    ; Dispatch all SET commands from here
        mov     kstatus,0               ; global status, success
        mov     dx,offset settab        ; Parse a keyword from the set table
        mov     bx,offset sethlp
        mov     ah,cmkey
        call    comnd
         ret
         nop
         nop
        jmp     bx                      ; execute analyzer routine
                                        ; returns rskp for success, else ret
SETCOM  endp

;   SET BAUD or SET SPEED

BAUDST  PROC    NEAR
        mov     dx,offset bdtab
        mov     bx,0
        call    keyend
         ret
         nop
         nop
        mov     si,portval
        mov     ax,[si].baud            ; Remember original value
        mov     [si].baud,bx            ; Set the baud rate
        call    dobaud                  ; Use common code
        jmp     rskp
BAUDST  ENDP

; SET BELL on or off

BELLST  PROC    NEAR
        mov     dx,offset ontab
        mov     bx,0
        call    keyend
         ret
         nop
         nop
        mov     flags.belflg,bl
        jmp     rskp
BELLST  ENDP

; SET BLOCK-CHECK

BLKSET  PROC    NEAR
        mov     dx,offset blktab
        mov     bx,0
        call    keyend
         ret
         nop
         nop
        mov     trans.chklen,bl         ; Use this char as the handshake
        mov     inichk,bl               ; Save here too
        jmp     rskp
BLKSET  ENDP

; SET COUNTER number    for script IF COUNTER number <command>
TAKECTR PROC    NEAR
        mov     min,0                   ; get decimal char code
        mov     max,65535               ; range is 0 to 65535 decimal
        mov     numhlp,offset takchlp   ; help message
        mov     numerr,0                ; error message
        call    num0                    ; convert number, return it in ax
        jc      takect2                 ; c = error
        mov     temp,ax                 ; recover numerical code
        mov     ah,cmcfm
        call    comnd                   ; Get a confirm
         ret                            ; Didn't get a confirm
         nop
         nop
        mov     ax,temp                 ; recover bx
        cmp     taklev,0                ; in a Take file?
        je      takect4                 ; e = no
        push    bx
        mov     bx,takadr
        mov     [bx].takctr,ax          ; set COUNT value
        pop     bx
takect2:jmp     rskp
takect4:mov     dx,offset takcerr       ; say must be in Take file
        jmp     reterr                  ; display msg and jmp rskp
TAKECTR ENDP

; SET DEBUG {OFF | ON | SESSSION | PACKETS}

DEBST   PROC       NEAR
        mov     dx,offset debtab
        mov     bx,offset debhlp
        call    keyend
         ret
         nop
         nop
        or      flags.debug,bl          ; set the mode, except for Off
        cmp     bx,0                    ; OFF?
        jne     deb0                    ; ne = no
        mov     flags.debug,0           ; Set the DEBUG flags off
deb0:   jmp     rskp
DEBST   ENDP

; SET DESTINATION   of incoming files

DESSET  PROC    NEAR
        mov     dx,offset destab
        mov     bx,0
        call    keyend
         ret
         nop
         nop
        mov     flags.destflg,bl        ; Set the destination flag
        cmp     bl,2                    ; Is dest the screen?
        jne     desa                    ; No, then done
        mov     flags.xflg,1            ; Remember it here
        jmp     rskp
desa:   mov     flags.xflg,0            ; Don't write to screen
        jmp     rskp
DESSET  ENDP

; SET DEFAULT-DISK    for sending/receiving, etc
; See cwdir in file mssker

; SET DELAY seconds   Used only for SEND command in local mode
SETDELY PROC    NEAR
        mov     min,0                   ; smallest acceptable value
        mov     max,63                  ; largest acceptable value
        mov     numhlp,offset delyhlp   ; help message
        mov     numerr,0                ; complaint message
        call    num0                    ; parse numerical input
        jc      setdly1                 ; c = error
        mov     trans.sdelay,al
setdly1:jmp     rskp                    ; success or failure
SETDELY ENDP

; SET DISPLAY Quiet/Regular/Serial/7-Bit/8-Bit (inverse of Set Remote on/off)
; Accepts two keywords in one command
disply  proc    near
        mov     ah,cmkey
        mov     dx,offset distab
        mov     bx,offset dishlp
        call    comnd
         ret
         nop
         nop
        mov     temp1,bx                ; save parsed value
        mov     temp2,0ffffh            ; assume no second keyword
        mov     comand.cmcr,1           ; bare CR's are allowed
        mov     ah,cmkey                ; parse for second keyword
        mov     dx,offset distab
        mov     bx,offset dishlp
        call    comnd
         jmp    short displ1            ; no keyword
         nop
        mov     temp2,bx                ; get key value
displ1: mov     comand.cmcr,0           ; bare CR's are not allowed
        mov     ah,cmcfm
        call    comnd                   ; confirm
         ret                            ; return on failure
         nop
         nop
        mov     ax,temp1                ; examine first key value
        call    dispcom                 ; do common code
        mov     ax,temp2                ; examine second key value
        call    dispcom
        jmp     rskp

dispcom:cmp     ax,0                    ; check range
        jle     displ3                  ; le = not legal, ignore
        cmp     al,7                    ; 7-8 bit value?
        jge     displ2                  ; ge = yes
        and     flags.remflg,not(dquiet+dregular+dserial)
        or      flags.remflg,al         ; set display mode
        ret                             ; check next key value
displ2: cmp     al,8                    ; set 8-bit wide display?
        ja      displ3                  ; a = bad value
        and     flags.remflg,not d8bit  ; assume want 7 bit mode
        cmp     al,7                    ; really want 7 bit mode?
        je      displ3                  ; e = yes
        or      flags.remflg,d8bit      ; set 8 bit flag
displ3: ret                             ; end of display common code
disply  endp


; Set Dump filename  for saving screen images on disk. [jrd]
; Puts filename in global string dmpname
setdmp  proc    near
        mov     dx,offset rdbuf         ; work area
        mov     rdbuf,0                 ; clear it
        mov     bx,offset dmphlp        ; help message
        mov     ah,cmfile               ; allow paths
        call    comnd
         ret
         nop
         nop
        mov     ah,cmcfm
        call    comnd
         ret
         nop
         nop
        mov     dx,offset rdbuf         ; assume we will use this text
        call    strlen                  ; filename given?
        mov     si,dx                   ; for strcpy
        cmp     cx,0                    ; length of user's filename
        jg      setdmp1                 ; g = filename is given
        mov     si,offset dmpdefnam     ; no name, use default instead
setdmp1:mov     di,offset dmpname       ; copy to globally available loc
        call    strcpy
        jmp     rskp
setdmp  endp

; SET EOF

SETEOF  PROC    NEAR
        mov     bx,0
        mov     dx,offset seoftab
        call    keyend
         ret
         nop
         nop
        mov     flags.eofcz,bl          ; set value
        jmp     rskp
SETEOF  ENDP

; SET EOL char (for Sent packets)
; Archic, here for downward compatibility
EOLSET  PROC    NEAR
        mov     stflg,'S'               ; set send/receive flag to Send
        jmp     sreol                   ; use Set Send/Rec routine do the work
EOLSET  ENDP

; SET ERRORLEVEL number
SETERL  PROC    NEAR
        mov     numhlp,offset erlhlp    ; help
        mov     numerr,0                ; error message
        mov     min,0                   ; smallest number
        mov     max,255                 ; largest magnitude
        call    num0                    ; parse numerical input
        jc      seterl1                 ; c = error
        mov     errlev,al               ; store result
seterl1:jmp     rskp                    ; success or failure
SETERL  ENDP

; SET ESCAPE character.
; Accept literal control codes and \### numbers. [jrd] 18 Oct 1987
ESCSET  PROC    NEAR
        mov     ah,cmfile
        mov     dx,offset rdbuf         ; work space
        mov     word ptr rdbuf,0        ; clear it
        mov     bx,offset eschlp        ; help
        call    comnd
         ret
         nop
         nop
        cmp     ah,0                    ; anything given?
        jne     escse1                  ; ne = yes
        mov     dx,offset ermes6        ; more parameters needed
        jmp     reterr
escse1: mov     ah,cmcfm                ; get a confirm
        call    comnd
         ret
         nop
         nop
        mov     si,offset rdbuf         ; source of chars
        call    katoi                   ; convert escaped numbers to binary
        cmp     ax,spc                  ; is it a control code?
        jae     escse2                  ; ae = no, complain
        cmp     ax,0                    ; non-zero too?
        je      escse2                  ; e = zero
        mov     trans.escchr,al         ; Save new value.
        jmp     rskp
escse2: mov     dx,offset escerr
        jmp     reterr
ESCSET  ENDP

SETATT  PROC    NEAR                    ; Set attributes on | off
        mov     dx,offset ontab
        mov     bx,0
        call    keyend
         ret
         nop
         nop
        mov     flags.attflg,bl
        jmp     rskp
SETATT  ENDP

; SET FILEWARNING

FILWAR  PROC    NEAR
        mov     dx,offset ontab
        mov     bx,0
        call    keyend
         ret
         nop
         nop
        mov     flags.flwflg,bl         ; Set the filewarning flag
        jmp     rskp
FILWAR  ENDP

; SET FLOW-CONTROL

FLOSET  PROC    NEAR
        mov     dx,offset flotab
        xor     bx,bx
        call    keyend
         ret
         nop
         nop
        mov     si,portval
        mov     [si].flowc,bx           ; Flow control value
        mov     [si].floflg,bl          ; Say if doing flow control
        jmp     rskp
FLOSET  ENDP

; SET HANDSHAKE
; Add ability to accept general decimal code. [jrd]

HNDSET  PROC    NEAR
        mov     dx,offset hndtab        ; table to scan
        mov     bx,offset hnd1hlp       ; help message
        mov     ah,cmkey
        call    comnd
         ret
         nop
         nop
        cmp     bl,0ffh                 ; want a general char code?
        jne     hnd1                    ; ne = no
        mov     min,0                   ; get decimal char code
        mov     max,31                  ; range is 0 to 31 decimal
        mov     numhlp,offset ctlhlp    ; help message
        mov     numerr,0                ; error message
        call    num0                    ; convert number, return it in ax
        jc      hnd2                    ; c = error
        mov     bx,ax                   ; recover numerical code
hnd1:
        mov     temp,bx                 ; handshake type
        mov     ah,cmcfm
        call    comnd                   ; Get a confirm
         ret                            ; Didn't get a confirm
         nop
         nop
        mov     bx,temp                 ; recover bx
        mov     si,portval
        cmp     bl,0                    ; Setting handshake off?
        je      hnd0                    ; Yes
        mov     [si].hndflg,1           ; And turn on handshaking
        mov     [si].hands,bl           ; Use this char as the handshake
        jmp     rskp
hnd0:   mov     [si].hndflg,0           ; No handshaking
hnd2:   jmp     rskp
HNDSET  ENDP

;   SET INCOMPLETE file disposition

ABFSET  PROC    NEAR
        mov     dx,offset abftab
        mov     bx,0
        call    keyend
         ret
         nop
         nop
        mov     flags.abfflg,bl         ; Set the aborted file flag
        jmp     rskp
ABFSET  ENDP
;
; Set Input commands (default-timeout, timeout-action, case, echo)
; By Jim Strudevant [jrs]
INPSET  PROC    NEAR
        mov     ah,cmkey                ; key word
        mov     dx,offset inptab        ; from inputtable
        mov     bx,0                    ; no hints
        call    comnd                   ; get the word
         ret                            ; they blew it
         nop
         nop
        jmp     bx                      ; do the sub command
;
; Set Input Default-timeout in seconds
;
inptmo: mov     numhlp,offset intoms    ; help
        mov     numerr,0                ; error message
        mov     min,0                   ; smallest number
        mov     max,-1                  ; largest magnitude
        call    num0                    ; parse numerical input
        jc      inptmo1                 ; c = error
        mov     script.indfto,ax        ; store result
inptmo1:jmp     rskp                    ; success or failure
;
; Set Input Timeout action (proceed or quit)
;
inpact: mov     dx,offset inactb        ; from this list
        mov     bx,0                    ; no hints
        call    keyend                  ; get it
         ret                            ; bad input
         nop
         nop
        mov     script.inactv,bl        ; save the action
        jmp     rskp                    ; good return
;
; Set Input Echo on or off
;
inpeco: mov     dx,offset ontab         ; from this list
        mov     bx,0                    ; no hints
        call    keyend                  ; get it
         ret                            ; bad input
         nop
         nop
        mov     script.inecho,bl        ; save the action
        jmp     rskp                    ; good return
;
; Set Input Case observe or ignore
;
inpcas: mov     dx,offset incstb        ; from this list
        mov     bx,0                    ; no hints
        call    keyend                  ; get it
         ret                            ; bad input
         nop
         nop
        mov     script.incasv,bl        ; save the action
        jmp     rskp                    ; good return
INPSET  ENDP

; SET KEY
; Jumps to new Set Key routine
setkey  proc    near
        cmp     stkadr,0        ; keyboard translator present?
        je      setk4           ; e = no, use this routine
        mov     bx,stkadr       ; yes, get offset of procedure
        jmp     bx              ; jump to keyboard translator
setk4:  mov     dx,offset ermes5
        jmp     reterr          ; else print error message
setkey  endp

; SET LOCAL-ECHO {ON | OFF}

LCAL    PROC    NEAR
        mov     dx,offset ontab
        mov     bx,0
        call    keyend
         ret
         nop
         nop
        mov     si,portval
        mov     [si].ecoflg,bl          ; Set the local echo flag
        jmp     rskp
LCAL    ENDP

; LOG  {PACKETS | SESSION | TRANSACTION} filename

setcpt  proc    near
        mov     dx,offset logtab        ; kinds of logging
        mov     bx,offset loghlp        ; help on kind of logging
        mov     ah,cmkey                ; parse keyword
        call    comnd
         ret
         nop
         nop
        mov     temp,bx                 ; Save the parsed value
        mov     dx,offset rdbuf         ; holds the complete filename
        mov     rdbuf,0                 ; clear buffer
        mov     bx,offset filhlp        ; ask for filename
        mov     ah,cmfile               ; allow paths
        call    comnd
         ret
         nop
         nop
        mov     ah,cmcfm
        call    comnd                   ; Get a confirm
         ret                            ;  Didn't get a confirm
         nop
         nop
        mov     bx,temp                 ; recover kind of logging
        mov     dx,offset rdbuf         ; length of filename to cx
        call    strlen                  ; length of given filename

        test    bl,logpkt               ; packet logging?
        jz      setcp2                  ; z = no, try others
        mov     dx,offset lpktnam       ; filename
        jcxz    setcp1                  ; z = no filename given
        mov     si,offset rdbuf         ; get new name
        mov     di,dx                   ; destination
        call    strcpy                  ; replace old name
setcp1: cmp     ploghnd,-1              ; packet log file already open?
        je      setcp6                  ; e = no, open it
        jmp     setcp16                 ; say file is open already

setcp2: test    bl,logses               ; session logging?
        jz      setcp4                  ; z = no, try others
        mov     dx,offset lsesnam       ; use default name
        jcxz    setcp3                  ; z = no filename given
        mov     si,offset rdbuf         ; get new name
        mov     di,dx                   ; destination
        call    strcpy                  ; replace old name
setcp3: cmp     sloghnd,-1              ; transaction file already open?
        je      setcp6                  ; e = no, open it
        jmp     setcp16                 ; say file is open already

setcp4: test    bl,logtrn               ; transaction logging?
        jz      setcp14                 ; z = no, error
        mov     dx,offset ltranam       ; use default name
        jcxz    setcp5                  ; z = no filename given
        mov     si,offset rdbuf         ; get new name
        mov     di,dx                   ; destination
        call    strcpy                  ; replace old name
setcp5: cmp     tloghnd,-1              ; transaction file already open?
        je      setcp6                  ; e = no, open it
        jmp     setcp16                 ; say file is open already

setcp6: mov     ax,dx                   ; place for filename for isfile
        call    isfile                  ; does file exist already?
        jc      setcp7                  ; c = does not exist so use create
        test    byte ptr filtst.dta+21,1fh ; file attributes, ok to write?
        jnz     setcp14                 ; nz = no, use error exit
        mov     ah,open2                ; open existing file
        mov     al,1+1                  ;  for writing and reading
        int     dos
        jc      setcp14                 ; if carry then error
        mov     bx,ax                   ; file handle for seeking
        mov     cx,0                    ; high order displacement
        mov     dx,0                    ; low order part of displacement
        mov     ah,lseek                ; seek to EOF (to do appending)
        mov     al,2                    ; says to EOF
        int     dos
        jmp     short setcp8

setcp7: test    filtst.fstat,80h        ; access problem?
        jnz     setcp14                 ; nz = yes, stop here
        mov     ah,creat2               ; function is create
        mov     cl,20H                  ; turn on archive bit
        mov     ch,0
        int     dos                     ; create the file, DOS 2.0
        jc      setcp14                 ; if carry bit set then error
        mov     bx,ax                   ; file handle

setcp8: cmp     temp,logpkt             ; packet logging?
        jne     setcp9                  ; ne = no
        mov     ploghnd,bx              ; save transaction log handle here
        jmp     short setcp12
setcp9: cmp     temp,logses             ; session logging?
        jne     setcp10                 ; ne = no
        mov     sloghnd,bx              ; save session log handle here
        jmp     short setcp12
setcp10:mov     tloghnd,bx              ; save transaction log handle here

setcp12:mov     ax,temp                 ; kind of Logging
        or      flags.capflg,al         ; accumulate kinds of logging
        jmp     rskp                    ; and return

setcp14:mov     dx,offset errcap        ; give error message
        jmp     reterr                  ; and display it

setcp16:mov     ah,prstr                ; file already open
        mov     dx,offset erropn
        int     dos
        jmp     rskp                    ; return success
setcpt  endp

; SET MODE LINE

MODL    PROC    NEAR
        mov     dx,offset ontab         ; parse an on or off
        mov     bx,0                    ; no special help
        call    keyend
         ret
         nop
         nop
        mov     flags.modflg,bl         ; set flag appropriately
        jmp     rskp
MODL    ENDP

; SET PARITY

SETPAR  PROC    NEAR
        mov     dx,offset partab
        mov     bx,0
        call    keyend
         ret
         nop
         nop
        mov     si,portval
        mov     [si].parflg,bl          ; Set the parity flag
        cmp     bl,parnon               ; Resetting parity to none?
        je      setp0                   ; e = yes, reset 8 bit quote character
        mov     trans.ebquot,dqbin      ; we want quoting, active
        mov     dtrans.ebquot,dqbin     ; we want quoting, our default
        jmp     short setp1
setp0:  mov     trans.ebquot,'Y'        ; say will quote upon request
        mov     dtrans.ebquot,'Y'       ; and our default
        setp1:  jmp     rskp
SETPAR  ENDP

; SET PROMPT  Allow user to change the "Kermit-MS>" prompt
; {string} and \number notation permitted to represent special chars. [jrd]

PROMSET PROC    NEAR
        mov     ah,cmtxt
        mov     bx,offset rdbuf         ; Read in the prompt
        mov     word ptr [bx],0         ; clear buffer
        mov     dx,offset prmmsg
        call    comnd
         ret
         nop
         nop
        cmp     rdbuf,0                 ; Just a bare CR?
        jne     prom0                   ; ne = no
        mov     ax,offset kerm          ; yes, restore default prompt
        jmp     prom1
prom0:  push    si                      ; parse \### constants into
        push    di                      ;  1 byte binary numbers inline
        mov     si,offset rdbuf         ; source = new prompt string
        mov     byte ptr [si-1+length rdbuf],0 ; plant null terminator
        mov     di,offset prm           ; destination
        call    cnvlin                  ; convert \### in string to binary
        pop     di
        pop     si
        mov     bx,cx                   ; get byte count
        add     bx,offset prm           ; point to null terminator
        mov     byte ptr [bx],'$'       ; End of string
        mov     ax,offset prm
prom1:  mov     prmptr,ax               ; Remember it
        jmp     rskp
PROMSET ENDP

; SET SERVER TIMEOUT

SETSRV  PROC    NEAR
        mov     dx,offset srvtab        ; set server table
        mov     bx,0                    ; use table for help
        mov     ah,cmkey                ; get keyword
        call    comnd
         ret
         nop
         nop
        mov     min,0                   ; smallest acceptable value
        mov     max,255                 ; largest acceptable value, one byte
        mov     numhlp,offset srvthlp   ; help message
        mov     numerr,0                ; complaint message
        call    num0                    ; parse numerical input
        jc      setsrv1                 ; c = error
        mov     srvtmo,al               ; store timeout value
setsrv1:jmp     rskp
SETSRV  ENDP

; SET RETRY value. Changes the packet retry limit. [jrd]

RETRYSET PROC   NEAR
        mov     min,1                   ; smallest acceptable value
        mov     max,63                  ; largest acceptable value
        mov     numhlp,offset retryhlp  ; help message
        mov     numerr,0                ; complaint message
        call    num0                    ; parse numerical input
        jc      retrys1                 ; c = error
        mov     maxtry,al
        shl     al,1                    ; quick multiply by two or three
        mov     imxtry,al               ; keep that much
        add     al,maxtry               ; try three times
        js      retrys1                 ; s = sign bit set, too much
        mov     imxtry,al               ; I packets get 3 times as many tries
retrys1:jmp     rskp
RETRYSET ENDP

; SET TAKE-ECHO  on or off

TAKSET  PROC    NEAR
        mov     dx,offset ontab
        mov     bx,0
        call    keyend
         ret
         nop
         nop
        mov     flags.takflg,bl
        jmp     rskp
TAKSET  ENDP

; SET TIMER     on or off during file transfer

TIMSET  PROC    NEAR
        mov     dx,offset ontab
        mov     bx,0
        call    keyend
         ret
         nop
         nop
        mov     flags.timflg,bl
        jmp     rskp
TIMSET  ENDP

; SET SEND parameters

SENDSET PROC    NEAR
        mov     stflg,'S'               ; Setting SEND parameter
sndst0: mov     dx,offset stsrtb        ; Parse a keyword
        mov     bx,0                    ; no specific help
        mov     ah,cmkey
        call    comnd
         ret                            ; bad user text
         nop
         nop
        jmp     bx                      ; do the action routine
SENDSET ENDP

; SET RECEIVE parameters

recset: mov     stflg,'R'               ; Setting RECEIVE paramter
        jmp     sndst0

remset  proc    near                    ; Set REMOTE ON/OFF
        mov     dx,offset ontab
        mov     bx,offset remhlp
        call    keyend
         ret
         nop
         nop
        and     flags.remflg,not (dquiet+dserial+dregular) ; no display bits
        or      bl,bl                   ; want off state? (same as regular)
        jz      remset1                 ; z = yes
        or      flags.remflg,dquiet     ; else on = quiet display
        jmp     short remset2
remset1:or      flags.remflg,dregular   ; off = regular display
remset2:jmp     rskp
remset  endp


; SET Send and Receive EOL char

sreol   PROC    NEAR
        mov     min,0                   ; lowest acceptable value
        mov     max,1FH                 ; largest acceptable value
        mov     numhlp,offset ctlhlp    ; Reuse help message
        mov     numerr,0                ; error message address
        call    num0                    ; get numerical input
        jc      sreol3                  ; c = error
        cmp     stflg,'S'               ; Setting SEND paramter?
        je      sreol1
        mov     trans.reol,al
        jmp     short sreol2
sreol1: mov     dtrans.seol,al
sreol2: mov     ah,dtrans.seol
        mov     trans.seol,ah
sreol3: jmp     rskp
sreol   ENDP


; SET SEND and RECEIVE start-of-header

srsoh:  mov     min,0
        mov     max,1FH
        mov     numhlp,offset ctlhlp    ; Reuse help message
        mov     numerr,0                ; error message
        call    num0            ; Common routine for parsing numerical input
        jc      srsoh2                  ; c = error
        cmp     stflg,'S'               ; Setting SEND paramter?
        je      srsoh1
        mov     trans.rsoh,al           ; set Receive soh
        jmp     short srsoh2
srsoh1: mov     trans.ssoh,al           ; set Send soh
srsoh2: jmp     rskp                    ; success or failure

; SET SEND and  RECEIVE TIMEOUT

srtim:  mov     min,0
        mov     max,94
        mov     numhlp,offset timhlp    ; Reuse help message
        mov     numerr,0                ; error message
        call    num0            ; Common routine for parsing numerical input
        jc      srtim3                  ; c = error
        cmp     stflg,'S'               ; Setting SEND paramter?
        je      srtim1
        mov     trans.rtime,al
        jmp     short srtim2
srtim1: mov     dtrans.stime,al
srtim2: mov     ah,dtrans.stime
        mov     trans.stime,ah
srtim3: jmp     rskp

; SET SEND and RECEIVE PACKET LENGTH

srpack: mov     min,20
        mov     max,maxpack
        mov     numhlp,offset pakhlp    ; help
        mov     numerr,offset pakerr    ; error message
        call    num0
        jc      srpak2                  ; c = error
        cmp     stflg,'S'               ; setting send value?
        jne     srpakr                  ; ne = receive
        mov     trans.slongp,ax         ; set send value
        mov     trans.slong,ax          ; and remember what we Set
        cmp     ax,94                   ; within normal packet range?
        ja      srpak2                  ; a = no
        mov     trans.spsiz,al          ; yes. update regular pkt size too
srpak2: jmp     rskp                    ; success or failure
srpakr: mov     trans.rlongp,ax         ; set receive value
        cmp     ax,94                   ; within normal packet range?
        ja      srpak4                  ; a = no
        mov     trans.rpsiz,al          ; yes. update regular pkt size too
srpak4: jmp     rskp


; SET SEND and RECEIVE number of padding characters

srnpd:  mov     min,0
        mov     max,99
        mov     numhlp,offset padhlp    ; help message
        mov     numerr,0                ; error message
        call    num0                    ; Parse numerical input
        jc      srnpd3                  ; c = error
        cmp     stflg,'S'               ; Setting SEND paramter?
        je      srnpd1                  ; e = yes
        mov     trans.rpad,al           ; set Receive padding
        jmp     short srnpd2
srnpd1: mov     dtrans.spad,al          ; set default Send padding
srnpd2: mov     al,dtrans.spad
        mov     trans.spad,al           ; update active array for I and S pkts
srnpd3: jmp     rskp                    ; success or failure

; SET SEND and RECEIVE padding character

srpad:  mov     min,0
        mov     max,127
        mov     numhlp,offset padhlp
        mov     numerr,offset padhlp
        call    num0                    ; Parse numerical input
        jc      srpad4                  ; c = error
        cmp     ah,127                  ; This is allowed
        je      srpad1
        cmp     ah,32
        jb      srpad1                  ; Between 0 and 31 is OK too
        mov     ah,prstr
        mov     dx,offset padhlp
        int     dos
srpad1: cmp     stflg,'S'               ; Send?
        je      srpad2                  ; e = yes, else Receive
        mov     trans.rpadch,al         ; store receive pad char
        jmp     short srpad3
srpad2: mov     dtrans.spadch,al        ; store Send pad char
srpad3: mov     ah,dtrans.spadch
        mov     trans.spadch,ah         ; update active array for I and S pkts
srpad4: jmp     rskp

; SET SEND and  RECEIVE control character prefix

srquo:  mov     min,33
        mov     max,126
        mov     numhlp,offset quohlp    ; help message
        mov     numerr,0                ; error message
        call    num0                    ; Parse numerical input
        jc      srquo3                  ; c = error
        cmp     stflg,'S'               ; Setting outgoing quote char?
        je      srquo1
        mov     trans.rquote,al         ; set Receive quote char
        jmp     short srquo2
srquo1: mov     dtrans.squote,al        ; set Send quote char
srquo2: mov     ah,dtrans.spadch
        mov     trans.spadch,ah         ; update active array for I and S pkts
srquo3: jmp     rskp

; SET SEND Pause number of milliseconds

srpaus: mov     min,0
        mov     max,127
        mov     numhlp,offset pauhlp    ; help
        mov     numerr,0
        call    num0                    ; Parse numerical input
        pushf                           ; save carry for error state
        cmp     stflg,'S'               ; Setting SEND paramter?
        je      srpau0
        popf
        mov     dx,offset ermes5        ; "Not implemented" msg
        jmp     reterr                  ; print error message
srpau0: popf
        jc      srpau1                  ; c = error
        mov     spause,al               ; store value
srpau1: jmp     rskp

; SET TRANSLATION INPUT   Connect mode translate incoming characters
; SET TRANS IN {Original-byte New-byte | ON | OFF}

SETRX   PROC    NEAR                    ; translate incoming serial port char
        mov     ah,cmkey
        mov     dx,offset trnstab       ; direction table (just one entry)
        mov     bx,0                    ; no help
        call    comnd
         ret
         nop
         nop
        mov     dx,offset rdbuf         ; our work space
        mov     word ptr rdbuf,0        ; insert terminator
        mov     bx,offset srxhlp1       ; first help message
        mov     ah,cmfile               ; parse a word
        call    comnd                   ; get incoming byte pattern
         ret                            ; error if none
         nop
         nop
        or      ah,ah                   ; any text given?
        jz      setr6                   ; nz = no
        mov     temp,ax                 ; save byte count here
        mov     ax,word ptr rdbuf       ; get first two characters
        or      ax,2020h                ; convert upper to lower case
        cmp     ax,'fo'                 ; first part of word OFF?
        je      setr6                   ; e = yes, go analyze
        cmp     ax,'no'                 ; word ON?
        je      setr6                   ; e = yes, go do it
        mov     si,offset rdbuf         ; convert text to number
        call    katoi                   ; number converter procedure, to ax
        jnc     setr1                   ; nc = success
        cmp     byte ptr temp+1,1       ; just one character given?
        jne     setr6                   ; ne = no, so bad code
setr1:  mov     min,ax                  ; save byte code here
        mov     dx,offset rdbuf         ; our work space
        mov     word ptr rdbuf,0        ; insert terminator
        mov     bx,offset srxhlp1       ; first help message
        mov     ah,cmfile               ; parse a word
        call    comnd                   ; get incoming byte pattern
         ret
         nop
         nop
        or      ah,ah                   ; any text given?
        jz      setr6                   ; z = no
        mov     temp,ax                 ; save byte count here
        mov     si,offset rdbuf         ; convert text to number
        call    katoi                   ; number converter procedure
        jnc     setr3                   ; nc = success
        cmp     byte ptr temp+1,1       ; just one character given?
        jne     setr6                   ; ne = no, so bad code or ON/OFF
setr3:  mov     max,ax                  ; save byte code here
        mov     ah,cmcfm                ; get a confirm
        call    comnd
         ret                            ; no confirm
         nop
         nop
        mov     bx,min                  ; bl = incoming byte code
        xor     bh,bh
        mov     ax,max                  ; al = local (translated) byte code
        mov     rxtable [bx],al         ; store in rx translate table
        jmp     rskp

setr6:  mov     ah,cmcfm                ; get a confirm
        call    comnd
         ret
         nop
         nop
        mov     dx,offset badrx         ; assume bad construction
        or      word ptr rdbuf,2020h    ; convert to lower case
        or      rdbuf+2,20h             ; first three chars
        cmp     word ptr rdbuf,'fo'     ; key word OFF?
        jne     setr8                   ; ne = no
        cmp     rdbuf+2,'f'             ; last letter of OFF?
        jne     setr8
        mov     rxtable+256,0           ; OFF is status byte = zero
        mov     dx,offset rxoffmsg      ; say translation is turned off
        jmp     setr9
setr8:  cmp     word ptr rdbuf,'no'     ; keyword ON?
        jne     setr9a                  ; ne = no, error
        mov     rxtable+256,1           ; ON is status byte non-zero
        mov     dx,offset rxonmsg       ; say translation is turned on
setr9:  cmp     intake,0                ; executing from a Take file?
        je      setr9a                  ; e = no
        cmp     flags.takflg,0          ; echo contents of Take file?
        je      setr10                  ; e = no
setr9a: mov     ah,prstr                ; bad number message
        int     dos
setr10: jmp     rskp
SETRX   ENDP

; SHOW TRANSLATE-RECEIVE
; Display characters being changed for Connect mode serial receive translator

SHORX   PROC    NEAR                    ; show translate table of incoming
                                        ; chars, only those changed
        mov     ah,cmcfm                ; get a confirm
        call    comnd
          ret                           ; no confirm
          nop
          nop
        mov     ah,prstr
        mov     dx,offset rxoffmsg      ; assume translation is off
        cmp     rxtable+256,0           ; is translation off?
        je      shorx0                  ; e = yes
        mov     dx,offset rxonmsg       ; say translation is on
shorx0: int     dos
        mov     dx,offset shormsg       ; give title line
        int     dos
        xor     cx,cx                   ; formatted line counter
        xor     bx,bx                   ; entry subscript
shorx1: cmp     rxtable[bx],bl          ; entry same as normal?
        je      shorx2                  ; e = yes, skip it
        call    shoprt                  ; print the entry
shorx2: inc     bx                      ; next entry
        cmp     bx,255                  ; done all entries yet?
        jbe     shorx1                  ; be = not yet
        mov     ah,prstr
        mov     dx,offset crlf          ; end with cr/lf
        int     dos
        jmp     rskp

shoprt: cmp     cx,4                    ; done five entries for this line?
        jb      shopr1                  ; b = no
        mov     ah,prstr
        mov     dx,offset crlf          ; break line now
        int     dos
        xor     cx,cx
shopr1: mov     ah,prstr
        mov     dx,offset shopm1        ; start of display
        int     dos
        xor     ah,ah
        mov     al,bl                   ; original byte code
        call    decout                  ; display its value
        mov     ah,prstr
        mov     dx,offset shopm2        ; intermediate part of display
        int     dos
        xor     ah,ah
        mov     al,rxtable[bx]          ; new byte code
        call    decout                  ; display its value
        mov     ah,prstr
        mov     dx,offset shopm3        ; last part of display
        int     dos
        inc     cx                      ; count item displayed
        ret
SHORX   ENDP

; SHOW MACRO [macro name]

SHOMAC  PROC    NEAR
        mov     ah,cmfile
        mov     dx,offset rdbuf
        mov     bx,offset shmmsg
        mov     comand.cmper,1          ; don't react to \%x variables
        call    comnd
         ret
         nop
         nop
        mov     al,ah
        mov     ah,0
        mov     shmcnt,ax               ; save length of user spec
        mov     ah,cmcfm
        call    comnd
         ret
         nop
         nop
        mov     si,offset mcctab        ; table of macro names
        cld
        lodsb
        mov     cl,al                   ; number of macro entries
        mov     ch,0
        jcxz    shom6                   ; z = none
        mov     temp,0                  ; count of macros displayed
shom2:  push    cx                      ; save loop counter
        lodsb                           ; length of macro name
        mov     ah,0
        mov     cx,shmcnt               ; length of user's string
        jcxz    shom4                   ; show all names
        cmp     al,cl                   ; mac name shorter that user spec?
        jb      shom5                   ; b = yes, no match
        push    ax
        push    si                      ; save these around match test
        mov     di,offset rdbuf         ; user's string
shom3:  mov     ah,[di]
        inc     di
        lodsb                           ; al = mac name char, ah = user char
        and     ax,not 2020h            ; clear bits (uppercase chars)
        cmp     ah,al                   ; same?
        loope   shom3                   ; while equal, do more
        pop     si                      ; restore regs
        pop     ax
        jne     shom5                   ; ne = no match
shom4:  call    shom9                   ; show this name
shom5:  add     si,ax                   ; no match, skip name
        add     si,3                    ; and '$', and string pointer
        pop     cx                      ; recover loop counter
        loop    shom2                   ; one less macro to examine

        cmp     temp,0                  ; did we show any macros?
        jne     shom7                   ; ne = yes
shom6:  mov     ah,prstr
        mov     dx,offset shom9m3       ; no entries found
        int     dos
shom7:  mov     ah,prstr                ; Summary line
        mov     dx,offset shom9m1       ; free space: name entries
        int     dos
        mov     ax,offset mcctab+mcclen
        sub     ax,mccptr               ; compute # of free name bytes
        call    decout
        mov     ah,prstr
        mov     dx,offset shom9m2       ; body characters
        int     dos
        mov     ax,offset macbuf+maclen
        sub     ax,macptr
        call    decout
        mov     ah,prstr
        mov     dx,offset crlf
        int     dos
        jmp     rskp                    ; return successfully to caller

                                        ; worker, show mac name and def
shom9:  push    ax                      ; call with si pointing at macro
        push    si                      ; name, byte ptr [si-1] = length
        cmp     byte ptr[si],0          ; name starts with null char?
        je      shom9e                  ; yes, TAKE file, ignore
        mov     ah,prstr
        mov     dx,offset crlfsp        ; go to new line
        int     dos
        inc     temp                    ; count displayed macros
        mov     dx,si                   ; Print macro name
        int     dos
        mov     dx,offset eqs           ; display equals sign
        int     dos
        mov     al,[si-1]               ; length of macro name
        mov     ah,0
        add     si,ax                   ; skip over name
        add     si,1                    ; skip '$' field
        mov     si,[si]                 ; si = offset of count + string
        mov     cl,byte ptr [si]        ; length of string
        mov     ch,0
        inc     si                      ; si = offset of string text proper
shom9a: lodsb                           ; get a byte into al
        cmp     al,' '                  ; control char?
        jae     shom9c                  ; ae = no
        cmp     al,cr                   ; carriage return?
        jne     shom9b                  ; ne = no
        mov     ah,prstr
        mov     dx,offset shom9m4       ; show <cr>
        int     dos
        cmp     cx,1                    ; more to show?
        je      shom9d                  ; e = no
        mov     dx,offset crlfsp        ; show cr,lf,space,space
        int     dos
        cmp     byte ptr[si],lf         ; cr followed by linefeed?
        jne     short shom9d
        inc     si                      ; skip the leading lf
        dec     cx
        jmp     short shom9d
shom9b: push    ax
        mov     ah,conout
        mov     dl,5eh                  ; caret
        int     dos
        pop     ax
        add     al,'A'-1                ; add offset to make printable letter
shom9c: mov     ah,conout
        mov     dl,al                   ; display it
        int     dos
shom9d: loop    shom9a                  ; do whole string
shom9e: pop     si
        pop     ax
        ret
SHOMAC  ENDP

SHCOM   PROC    NEAR                    ; Show Modem
        mov     ah,cmcfm
        call    comnd                   ; Get a confirm
         ret                            ; Didn't get a confirm
         nop
         nop
        mov     dx,offset crlf
        mov     ah,prstr
        int     dos                     ; print a crlf
        mov     bx,offset stcom         ; table of items to be shown
        call    statc                   ; finish in common code
         nop
         nop
         nop
        call    shomodem
         nop
         nop
         nop
        jmp     rskp
SHCOM   ENDP
SHFILE  PROC    NEAR                    ; Show File
        mov     ah,cmcfm
        call    comnd                   ; Get a confirm
         ret                            ; Didn't get a confirm
         nop
         nop
        mov     dx,offset crlf
        mov     ah,prstr
        int     dos                     ; print a crlf
        mov     bx,offset stfile        ; table of items to be shown
        jmp     statc                   ; finish in common code
SHFILE  ENDP

SHLOG   PROC    NEAR                    ; Show Log
        mov     ah,cmcfm
        call    comnd                   ; Get a confirm
         ret
         nop
         nop
        mov     dx,offset crlf
        mov     ah,prstr
        int     dos                     ; print a crlf
        mov     bx,offset stlog         ; table of items to be shown
        jmp     statc                   ; finish in common code
SHLOG   ENDP
SHPRO   PROC    NEAR                    ; Show Protocol
        mov     ah,cmcfm
        call    comnd                   ; Get a confirm
         ret
         nop
         nop
        mov     dx,offset crlf
        mov     ah,prstr
        int     dos                     ; print a crlf
        mov     bx,offset stpro         ; table of items to be shown
        jmp     statc                   ; finish in common code
SHPRO   ENDP
SHSCPT  PROC    NEAR                    ; Show Script
        mov     ah,cmcfm
        call    comnd                   ; Get a confirm
         ret
         nop
         nop
        mov     dx,offset crlf
        mov     ah,prstr
        int     dos                     ; print a crlf
        mov     bx,offset stscpt        ; table of items to be shown
        jmp     statc                   ; finish in common code
SHSCPT  ENDP
SHSERV  PROC    NEAR                    ; Show Server
        mov     ah,cmcfm
        call    comnd                   ; Get a confirm
         ret
         nop
         nop
        mov     dx,offset crlf
        mov     ah,prstr
        int     dos                     ; print a crlf
        mov     bx,offset stserv2       ; do heartbeak item
        call    statc
         nop
         nop
         nop
        mov     dx,offset crlf
        mov     ah,prstr
        int     dos
        mov     bx,offset stserv        ; table of items to be shown
        jmp     statc                   ; finish in common code
SHSERV  ENDP

SHTERM  PROC    NEAR                    ; Show Terminal
        mov     ah,cmcfm
        call    comnd                   ; Get a confirm
         ret
         nop
         nop
        mov     dx,offset crlf
        mov     ah,prstr
        int     dos                     ; print a crlf
        mov     bx,offset stterm        ; table of items to be shown
        jmp     statc                   ; use common code
SHTERM  ENDP

; STATUS command. Revised by [jrd]

STATUS  PROC    NEAR
        mov     ah,cmcfm
        call    comnd                   ; Get a confirm
         ret
         nop
         nop
        mov     dx,offset crlf
        mov     ah,prstr
        int     dos                     ; print a crlf
STAT0:  call    cmblnk                  ; clear the screen
        call    locate                  ; home the cursor
        mov     bx,offset sttab         ; table to control printing

STATC:  push    es                      ; STAT0 is an external ref (in mster)
        push    di
        mov     cx,ds
        mov     es,cx
        cld
        xor     cx,cx                   ; column counter
stat1:  cmp     word ptr [bx],0         ; end of table?
        je      statx                   ; e = yes
        cld                             ; string direction is forward
        mov     di,offset rdbuf         ; point to destination buffer
        mov     byte ptr[di],spc        ; start with two spaces
        inc     di
        mov     byte ptr[di],spc
        inc     di
        push    cx                      ; save column number
        push    bx
        call    [bx].sttyp              ; call appropriate routine
        pop     bx
        pop     cx
        sub     di,offset rdbuf         ; number of bytes used
        add     cx,di                   ; new line col count
        push    cx                      ; save col number around print
        mov     cx,di                   ; how much to print now
        mov     di,offset rdbuf         ; source text
        cmp     cx,2                    ; nothing besides our two spaces?
        jbe     stat5                   ; e = yes, forget it
        call    prtscr                  ; print counted string
stat5:  pop     cx
        add     bx,size stent           ; look at next entry
        cmp     word ptr [bx],0         ; at end of table?
        je      statx                   ; e = yes
        cmp     cx,38                   ; place for second display?
        jbe     stat2                   ; be = only half full
        mov     dx,offset crlf          ; over half full. send cr/lf
        mov     ah,prstr
        int     dos
        xor     cx,cx                   ; say line is empty now
        jmp     stat1
stat2:  mov     ax,cx
        mov     cx,38                   ; where we want to be next time
        sub     cx,ax                   ; compute number of filler spaces
        or      cx,cx
        jle     stat4                   ; nothing to do
        mov     ah,conout
        mov     dl,' '
stat3:  int     dos                     ; fill with spaces
        loop    stat3                   ; do cx times
stat4:  mov     cx,38                   ; current column number
        jmp     stat1                   ; and do it
statx:  pop     di
        pop     es
        jmp     rskp
STATUS  ENDP

; handler routines for status
; all are called with di/ destination buffer, bx/ stat ptr. They can change
; any register except es:, must update di to the end of the buffer.

; copy the message into the buffer
stmsg   proc    near
        push    ds
        pop     es              ; ensure es points to datas segment
        mov     si,[bx].msg     ; get message address
stms1:  lodsb                   ; get a byte
        stosb                   ; drop it off
        cmp     al,'$'          ; end of message?
        jne     stms1           ; no, keep going
        dec     di              ; else back up ptr
        ret
stmsg   endp

; get address of test value in stent. Returns address in si
stval   proc    near
        mov     si,[bx].basval  ; get base value
        cmp     si,0            ; any there?
        je      stva1           ; no, keep going
        mov     si,[si]         ; yes, use as base address
stva1:  add     si,[bx].tstcel  ; add offset of test cell
        ret                     ; and return it
stval   endp

; print a single character
onechr  proc    near
        call    stmsg           ; copy message part first
        call    stval           ; pick up test value address
        mov     al,[si]         ; this is char to print
        cmp     al,' '          ; printable?
        jae     onech1          ; yes, keep going
        add     al,64           ; make printable
        mov     byte ptr [di],5eh       ; caret
        inc     di              ; note ctrl char
onech1: stosb                   ; drop char off
        ret
onechr  endp

; numeric field
stnum   proc    near            ; for 8 bit numbers
        call    stmsg           ; copy message
        call    stval           ; pick up value address
        mov     al,[si]         ; get value
        mov     ah,0            ; high order is 0
        call    outnum          ; put number into buffer
        ret
stnum   endp

stlnum  proc    near            ; for 16 bit numbers [jrd]
        call    stmsg           ; copy message
        call    stval           ; pick up value address
        mov     ax,[si]         ; get value
        call    outnum          ; put number into buffer
        ret
stlnum  endp

; Common routine for parsing numerical input
; Enter with numhlp = offset of help message, numerr = offset of optional
;  error message, min, max = allowable range of values.
; Returns value in ax, or does parse error return.
; Changes ax,bx,dx,si.                  [jrd] 18 Oct 1987
num0:   mov     dx,offset rdbuf+1       ; were to put text
        mov     word ptr rdbuf,0        ; clear the buffer
        mov     bx,numhlp               ; help text
        mov     ah,cmfile               ; get a word
        call    comnd
         ret
         nop
         nop
        mov     ah,cmcfm
        call    comnd                   ; Get a confirm
         ret
         nop
         nop
        mov     si,offset rdbuf+1
        cmp     rdbuf+1,'\'             ; already quoted?
        je      num0a                   ; e = yes
        mov     rdbuf,'\'               ; add a numerical quote
        dec     si                      ; point to our escape char
num0a:  call    katoi                   ; convert number in rdbuf
        jc      num0er                  ; c = no number, error
        cmp     ax,max                  ; largest permitted value
        ja      num0er                  ; a = error
        cmp     ax,min                  ; smallest permitted value
        jb      num0er                  ; b = error
        clc
        ret                             ; return value in ax

num0er: mov     ah,prstr
        mov     dx,numerr               ; comand-specific error message, if any
        cmp     dx,0                    ; was any given?
        je      num0e1                  ; e = no, use generic msg
        int     dos                     ; show given error message
        jmp     short num0e2
num0e1: mov     dx,offset nummsg1       ; get address of numeric error message
        int     dos
        mov     ax,min                  ; smallest permitted number
        call    decout                  ; display decimal number in ax
        mov     ah,prstr
        mov     dx,offset nummsg2       ; "and"
        int     dos
        mov     ax,max                  ; largest permitted number
        call    decout
num0e2: stc
        ret
num0e3: mov     ah,prstr
        mov     dx,offset ermes7        ; say command not executed
        int     dos
        stc
        ret

; translate the number in ax
outnum  proc    near
        mov     dx,0
        mov     bx,10
        div     bx              ; divide to get digit
        push    dx              ; save remainder digit
        or      ax,ax           ; test quotient
        jz      outnu1          ; zero, no more of number
        call    outnum          ; else call for rest of number
outnu1: pop     ax              ; get digit back
        add     al,'0'          ; make printable
        stosb                   ; drop it off
        ret
outnum  endp

; on/off field
onoff   proc    near
        call    stmsg           ; copy message
        call    stval           ; get value cell
        mov     al,[si]
        mov     si,offset onmsg
        mov     cx,2            ; assume 2-byte 'ON' message
        or      al,al           ; test value
        jnz     onof1           ; on, have right msg
        mov     si,offset offmsg
        mov     cx,3
onof1:  rep     movsb           ; copy right message in
        ret
onoff   endp

; print first message if false, second if true
msg2    proc    near
        call    stval           ; get value cell
        mov     al,[si]
        mov     si,[bx].msg     ; assume off
        or      al,al           ; is it?
        jz      msg21           ; yes, continue
        mov     si,[bx].val2    ; else use alternate message
msg21:  jmp     stms1           ; handle copy and return
msg2    endp

; search a keyword table for a value, print that value
srchkw  proc    near
        call    stmsg           ; first print message
        call    stval
        mov     al,[si]         ; get value to hunt for
        mov     ah,0            ; high order is 0
        mov     bx,[bx].val2    ; this is table address
        jmp     prttab          ; and look in table
srchkw  endp

; search a keyword table for a bit value, print that value. [jrd]
srchkb  proc    near
        call    stmsg                   ; first print message
        call    stbval                  ; get bit set or reset
        mov     ah,0                    ; al has 0/1, high order is 0
        mov     bx,[bx].val2            ; this is table address
        jmp     prttab                  ; and look in table
srchkb  endp

; get address of test value in stent.  Returns address in si. [jrd]
stbval  proc    near
        mov     si,[bx].basval          ; get address of test value
        cmp     si,0                    ; any there?
        je      stbva1                  ; no, quit with no match
        mov     ax,[si]                 ; get value
        test    ax,[bx].tstcel          ; bit test value against data word
        jz      stbva1                  ; z = they don't match
        mov     ax,1                    ;  match
        ret
stbva1: mov     ax,0                    ; no match
        ret                             ; and return it
stbval  endp


; Print the drive name
drnum   proc    near
        call    stmsg           ; copy message part first
        call    stval           ; pick up test value address
        mov     ah,gcurdsk      ; Get current disk
        int     dos
        inc     al              ; We want 1 == A (not zero)
        mov     curdsk,al
        add     al,'@'          ; Make it printable
        cld
        stosb
        mov     word ptr [di],'\:'
        add     di,2            ; end with a colon and backslash
        mov     byte ptr [di],0 ; terminate in case drive is not ready
        mov     dl,0            ; get current drive
        mov     ah,gcd          ; get current directory
        mov     si,di           ; current working buffer position
        int     dos
        push    cx
        push    dx
        mov     dx,di           ; directory string
        call    strlen          ; length of path part to cx
        cmp     cx,26           ; too long to show the whole thing?
        jbe     drnum3          ; be = is ok, show the whole path
        push    di              ; scan backward for last backslash
        mov     al,'\'          ; thing to search for
        std                     ; backward
        mov     di,si           ; start of buffer
        add     di,cx           ; length of string
        repne   scasb           ; scan backward for a backslash
        jcxz    drnum2          ; should not happen, but then again
        repne   scasb           ; do again for second to last path part
drnum2: cld                     ; reset direction flag
        dec     di              ; move di two places preceding backslash
        mov     [di],'--'       ; insert a missing path indicator
        dec     di
        mov     byte ptr [di],'-'
        mov     si,di           ; we will show just this part
        pop     di              ; recover main status pointer
drnum3: pop     dx
        pop     cx

drnum4: lodsb                   ; copy until null terminator
        stosb
        cmp     al,0            ; end of string?
        jne     drnum4          ; ne = no
        dec     di              ; offset inc of stosb
        ret
drnum   endp


; Print the screen-dump filename [jrd]

pasz    proc    near
        call    stmsg           ; copy message part
        mov     si,[bx].val2    ; address of asciiz string
pasz1:  lodsb                   ; get a byte
        cmp     al,0            ; at end yet?
        je      pasz2           ; e = yes
        stosb                   ; store in buffer
        jmp     short pasz1     ; keep storing non-null chars
pasz2:  ret
pasz    endp

; print the End-of-Line characters
preol   proc    near
        call    stmsg           ; display leadin part of message
        mov     al,dtrans.seol  ; send eol char
        add     al,40H          ; make it printable
        stosb
        mov     si,offset mseol2 ; second part of message
        call    stms1           ; add that
        mov     al,trans.reol   ; receive eol char
        add     al,40H          ; make it printable
        stosb
        ret
preol   endp

; print Send Delay and Pause
prsnd   proc    near
        call    stmsg           ; display leadin part of msg
        mov     al,trans.sdelay ; Send Delay (sec)
        xor     ah,ah
        call    outnum
        mov     si,offset sndmsg2 ; second part of msg
        call    stms1           ; add that
        mov     al,spause       ; Send Pause (millisec)
        call    outnum
        mov     si,offset sndmsg3 ; last part of msg
        call    stms1           ; add it too
        ret
prsnd   endp

; Print the handshake
prhnd:  mov     si,offset handst        ; copy in initial message
        call    stms1
        mov     si,offset nonmsg        ; assume no handshake
        mov     bx,portval
        cmp     [bx].hndflg,0           ; Is handshaking in effect?
        jne     prh0                    ; Yes, print what we're using
        jmp     stms1                   ; no, say so and return
prh0:   mov     al,5eh                  ; Doing handshaking with control char
        stosb
        mov     al,[bx].hands
        add     al,40H                  ; Make printable
        stosb                           ; put in buffer
        ret                             ; and return

; Print the pad character in AL
prpad:  cmp     al,127                  ; Are they using a delete?
        jne     prpad0
        mov     ah,prstr
        mov     dx,offset delmsg
        int     dos
        ret
prpad0: mov     dl,5eh                  ; caret
        mov     ah,conout
        push    ax
        int     dos
        pop     ax
        mov     dl,al
        add     dl,40H                  ; Make printable
        int     dos
        ret

; Print value from table.  BX/address of table, AL/value of variable
prttab: push    cx                      ; save column count
        mov     cl,[bx]                 ; Number of entries in our table
        inc     bx                      ; Point to the data
prtt0:  mov     dl,[bx]                 ; Length of keyword
        inc     bx                      ; Point to keyword
        mov     dh,0
        inc     dx                      ; Account for "$" in table
        mov     si,dx                   ; Put to index register
        cmp     ax,[bx+si]              ; Is this the one?
        je      prtt1
        add     bx,dx                   ; Go to end of keyword
        add     bx,2                    ; Point to next keyword
        dec     cl                      ; Any more keywords to check?
        jnz     prtt0                   ; Yes, go to it
        mov     bx,offset prterr
prtt1:  mov     si,bx
        pop     cx                      ; recover column count
        jmp     stms1                   ; copy in message

; Print the baud rate

BAUDPRT PROC     NEAR
        mov     si,offset baudrt        ; "Baud rate is"
        call    stms1                   ; display that part
        call    getbaud                 ; read baud rate first
        mov     bx,portval
        mov     ax,[bx].baud
        cmp     al,byte ptr bdtab       ; number of table entries
        jb      bdprt5                  ; b = in table
        mov     si,offset unrec         ; say unrecognized value
        jmp     stms1                   ; display text and return
bdprt5: mov     bx,offset bdtab         ; show ascii rate from table
        call    prttab
        ret
BAUDPRT ENDP

; display Take/Macro COUNT
stcnt   proc    near
        call    stmsg                   ; display leadin part of msg
        cmp     taklev,0                ; in a Take file or macro?
        jne     stcnt1                  ; ne = yes
        mov     si,offset nonemsg       ; say none
        call    stms1
        ret
stcnt1: push    bx
        mov     bx,takadr               ; current Take structure
        mov     ax,[bx].takctr          ; get COUNT
        pop     bx
        call    outnum
        ret
stcnt   endp

; ALARM time
stalr   proc    near
        call    stmsg                   ; display leading part of msg
        push    bx                      ; preserve register
        mov     bx,0                    ; position index
stalr1: push    bx                      ; save around calls
        cmp     alrhms[bx],10           ; two digits?
        jae     stalr2                  ; ae = yes
        mov     al,'0'
        stosb                           ; show leading zero
stalr2: mov     al,alrhms[bx]           ; show time component
        mov     ah,0
        call    outnum
        pop     bx                      ; recover index
        inc     bx
        cmp     bx,3                    ; done all fields?
        jae     stalr3                  ; ae = yes
        mov     al,':'
        stosb
        jmp     short stalr1            ; do next field
stalr3: pop     bx
        ret
stalr   endp

; Jumping to this location is like retskp.    It assumes the instruction
;    after the call is a jmp addr

RSKP    PROC    NEAR
        pop     bp
        add     bp,3
        push    bp
        ret
RSKP    ENDP

; Jumping here is the same as a ret

R       PROC    NEAR
        ret
R       ENDP

; routine to print an error message, then retskp
; expects message in dx
reterr  proc    near
        mov     ah,prstr
        int     dos
        jmp     rskp
reterr  endp

code    ends

;; Additional data segment material placed here to aid MASM 4
datas   segment public 'datas'
ermes1  db      cr,lf,'?Too many macro names$'
ermes2  db      cr,lf,bell,'?No room for Take file buffer or Macro definition'
        db      cr,lf,bell,'$'
ermes4  db      cr,lf,'?Too many active Take files and Macros',cr,lf, bell,'$'
ermes5  db      cr,lf,'?Not implemented$'
ermes6  db      cr,lf,'?More parameters are needed$'
ermes7  db      cr,lf,'?Command not executed$'
errcap  db      cr,lf,'?Unable to open that file$'
erropn  db      cr,lf,'?Log file is already open$'
askhlp1 db      'Variable name  then  prompt string$'
askhlp2 db      'Prompt string$'
askhlp3 db      'Enter a line of text$'
filhlp  db      ' Output filename for the log$'
dishlp  db      cr,lf,' Quiet (no screen writing), Regular (normal),'
        db      ' Serial (non-formatted screen)'
        db      cr,lf,' and/or 7-BIT (default) or 8-BIT wide characters.$'
remhlp  db      cr,lf,' OFF to show file transfer display,'
        db      ' ON for quiet screen$'
macmsg  db      ' Specify macro name followed by body of macro, on same line$'
shmmsg  db      ' name of macro, or carriage return to see all$'
prmmsg  db      cr,lf
        db    ' Enter new prompt string or nothing to regain regular prompt.'
        db      cr,lf,' Use \123 notation for special chars (Escape is \27)$'

srxhlp1 db      cr,lf,' Enter   code for received byte   code for'
        db      ' local byte ',cr,lf,' use ascii characters themselves or'
        db      cr,lf,' numerical equivalents of  \nnn  decimal'
        db      ' or \Onnn  octal or \Xnnn  hexadecimal',cr,lf
        db      ' or keywords  ON  or  OFF  (translation is initially off)'
        db      cr,lf,'$'
shormsg db      cr,lf,' Translation table of received byte codes while'
        db      ' in CONNECT mode -'
        db      cr,lf,' Format: [received byte (decimal) -> local byte'
        db      ' (decimal)]',cr,lf,'$'
shopm1  db      ' [\$'                  ; Show Translation material
shopm2  db      ' -> \$'
shopm3  db      '] $'
badrx   db      cr,lf,'?Expected ON, OFF, or \nnn$'
rxoffmsg db     cr,lf,' Input Translation is off$'
rxonmsg db      cr,lf,' Input Translation is on$'
rxtable equ THIS BYTE           ; build 256 byte Translation Input table
        maketab                 ; table rxtable is used by Connect mode
stkadr  dw      0       ; non-zero if replacement keyboard xlator present
prterr  db      '?Unrecognized value$'
takchlp db      cr,lf,'Value 0 to 65535 for COUNT in script IF COUNT command$'
takcerr db      cr,lf,'?Note: command is valid only in Take files and Macros$'
defpmp  db      'Definition string: $'
nonmsg  db      'none$'
delmsg  db      'delete$'
onmsg   db      'on'
offmsg  db      'off'
logmsg  db      'Logging of Packets, Session, Transaction, plus'
        db      ' screen dump file -$'
lpktnam db      'PACKET.LOG',54 dup (0) ; default packet log filename
lsesnam db      'KERMIT.LOG',54 dup (0) ; default capture/session filename
ltranam db      'TRANSACT.LOG',52 dup (0); default transaction log filename
dmpdefnam db    'KERMIT.SCN',0          ; asciiz default screen dump filename
dmpname db      'KERMIT.SCN',54 dup (0) ; file name for screen dumps [jrd]
lsesmsg db      'Session log:     $'
lpktmsg db      'Packet log:      $'
ltramsg db      'Transaction log: $'
dmpmsg  db      'Dump screen:     $'
dmpmsg2 db      'Dump screen: $'        ; for general STATUS display
tmp     db      ?,'$'
modst   db      'Mode line: $'
locst   db      'Local echo: $'
belon   db      'Ring bell after transfer$'
beloff  db      'No bell after transfer$'
vtemst  db      'Terminal emulation: $'         ; terminal emulator
portst  db      'Communications port: $'
capmsg  db      'Logging: $'
eofmsg  db      'EOF mode: $'
flost   db      'No flow control used$'
floxmsg db      'Flow control: xon/xoff $'
handst  db      'Handshake used: $'
destst  db      'File destination: $'
diskst  db      'Path: $'
blokst  db      'Block check used: $'
sqcst   db      'Send control char prefix: $'
rqcst   db      'Receive control char prefix: $'
debon   db      'Debug: $'
flwon   db      'Warning (filename change): $'
parmsg  db      'Parity: $'
abfdst  db      'Discard incomplete file$'
abfkst  db      'Keep incomplete file$'
sndmsg  db      'Send Delay: $'
sndmsg2 db      ' sec, Pause: $'
sndmsg3 db      ' ms$'
ssohst  db      'Send start-of-packet char: $'
rsohst  db      'Receive start-of-packet char: $'
meolst  db      'End-of-Line char  S: ',5eh,'$'
mseol2  db      '  R: ',5eh,'$'
stimst  db      'Send timeout (seconds): $'
rtimst  db      'Receive timeout (seconds): $'
spakst  db      'Send packet size: $'
rpakst  db      'Receive packet size: $'
snpdst  db      '# of send padding chars: $'
rnpdst  db      '# of receive padding chars: $'
spadst  db      'Padding char: $'
retrymsg db     'Retry send/receive packet limit: $'
dispst  db      'Display (vs Remote):$'
remost  db      'Remote (vs Display) $'
timmsg  db      'Timer: $'
srvmsg  db      'Timeout (sec) waiting for a transaction: $'
srvthlp db      'seconds, 0-255, waiting for a transaction$'
escmes  db      'Escape character: $'
scpmsg  db      'Script commands Echo, If, Input, Output, Pause, Reinput,'
        db      ' Transmit, Wait$'
sechmsg db      'Input echoing: $'
scasmsg db      'Case sensitivity: $'
stmo1msg db     'Timeout (seconds): $'
stmo2msg db     'Timeout-action: $'
takon   db      'Take-echo: $'
atton   db      'Attributes pkts: $'
baudrt  db      'Baud rate is $'
unrec   db      'unknown$'
stcntmsg db     'Take/Macro COUNT: $'
nonemsg db      'no active Take/Macro$'
sterlmsg db     'Errorlevel: $'
stalrmsg db     'Alarm time: $'
nummsg1 db      cr,lf,'?Use a number between $'
nummsg2 db      ' and $'
ctlhlp  db      ' Decimal number between 0 and 31$'
dmphlp  db      ' Filename to hold screen dumps$'
erlhlp  db      ' Decimal number between 0 and 255$'
pakerr  db      cr,lf,'?Choose a decimal number '
        db      'from 20 to 94 (normal) or to 1000 (long)$'
pakhlp  db      cr,lf,'Decimal number between 20 and 94 (normal) or '
        db      '1000 (long)$'
padhlp  db      cr,lf,' Decimal number between 0 and 31 or 127$'
pauhlp  db      ' Decimal number between 0 and 127$'
quohlp  db      ' Decimal number between 33 and 126$'
retryhlp db     ' Decimal number between 1 and 63$'
timhlp  db      ' Decimal number between 0 and 94$'
delyhlp db      ' Delay seconds before sending file (0-63)$'
eschlp  db      cr,lf,'Press literal control keys (ex: Control ]) or'
        db      ' enter in \nnn numerical form$'
escerr  db      cr,lf,'?Not a control code$'
hnd1hlp db      cr,lf,'XON (\17), XOFF (\19), CR (\13), LF (\10), BELL (\7),'
        DB      ' ESC (\27), NONE (\0)'
        db      cr,lf,' or "CODE" followed by decimal number$'
intoms  db      'number of seconds to wait before timeout',cr,lf,'$'
loghlp  db      cr,lf
        db     ' PACKET - during file transfers  (to default file PACKET.LOG)'
        db      cr,lf
        db     ' SESSION - during Connect mode   (to default file KERMIT.LOG)'
        db      cr,lf
        db     ' TRANSACTION - files transferred (to default file TRANSACT.LOG)'
        db      cr,lf,'  followed by an optional filename for the log.$'
debhlp  db      cr,lf,' PACKETS - during file transfers'        ; Debugging
        db      cr,lf,' SESSION - during Connect mode'
        db      cr,lf,' ON - both packets and session'
        db      cr,lf,' OFF - turns off all debugging$'
dohlp   db      cr,lf,'definitions of variables (\%n), or carriage return$'

sdshlp  db      cr,lf,'DISABLE or ENABLE access to selected Server commands:'
        db      cr,lf
        db      ' CD/CWD, DEL, DIR, FIN (incl BYE & LOGO), GET, HOST, MESSAGE,'
        db      ' SPACE, TYPE,',cr,lf,' and ALL.'
        db      cr,lf,'Also TEK (automatic invokation of Tek4010 graphics);'
        db      ' not a member of ALL.$'
servmsg db      'Server commands available to remote user: $'
scwdmsg db      'CD/CWD: $'
sdelmsg db      'DELETE: $'
sdirmsg db      'DIR:    $'
sfinmsg db      'FINISH: $'
sgetmsg db      'GET:    $'
shstmsg db      'HOST:   $'
ssndmsg db      'MESSAGE:$'
sspcmsg db      'SPACE:  $'
stypmsg db      'TYPE:   $'
stekmsg db      'Tek4010: $'

srvtab  db      1                       ; SET SERVER table
        mkeyw   'Timeout',1

sethlp  db      cr,lf
        db      '  Alarm    sec from now or HH:MM:SS  '
        db      '  Input timeout, etc  (for scripts)'
        db      cr,lf
        db      '  Attributes packets on/off          '
        db      '  Key         key-ident   definition'
        db      cr,lf
        db      '  Baud or Speed     many speeds      '
        db      '  Local-echo        on/off'
        db      cr,lf
        db      '  Bell    on/off    at end of xfers  '
        db      '  Mode-line         on/off'
        db      cr,lf
        db      '  Block-check-type  checksum/CRC     '
        db      '  Parity    even/odd/mark/space/none'
        db      cr,lf
        db      '  COUNT   number    a loop counter   '
        db      '  Port for i/o      1/2/COM1/COM2/etc'
        db      cr,lf
        db      '  Default-disk                       '
        db      '  Prompt  string   (new Kermit prompt)'
        db      cr,lf
        db      '  Debug   on/off    display packets  '
        db      '  Receive parameter  many things'
        db      cr,lf
        db      '  Delay   secs  before Sending file  '
        db      '  Remote    on/off  show xfer counts?'
        db      cr,lf
        db      '  Destination   Disk/Screen/Printer  '
        db      '  Retry limit for packet send/receive'
        db      cr,lf
        db      '  Display quiet/reg/serial show cnts?'
        db      '  Send parameter    many things'
        db      cr,lf
        db      '  Dump filespec     screen to disk   '
        db      '  Server parameter'
        db      cr,lf
        db      '  End-of-line char  cr or whatever   '
        db      '  Take-echo on/off  display commands?'
        db      cr,lf
        db      '  EOF Ctrl-Z/NoCtrl-Z  ^Z ends file? '
        db      '  Terminal  none, Heath-19, VT52, VT102,'
        db      cr,lf
        db      '  Errorlevel number   for DOS Batch  '
        db      '     and many terminal setup parameters'
        db      cr,lf
        db      '  Escape char  ^]   or whatever      '
        db      '  Timer     on/off  time packet waiting'
        db      cr,lf
        db      '  Flow-control      xon-xoff or none '
        db      "  Translation IN  Connect mode rcv'd char"
        db      cr,lf
        db      '  Handshake xon/xoff/cr/lf/bell/esc..'
        db      '  Warning   on/off  if file renamed'
        db      cr,lf
        db      '  Incomplete file   keep/discard'
        db      cr,lf,'$'

settab   db     37                                      ; Set table
        mkeyw   'Alarm',setalrm
        mkeyw   'Attributes',setatt
        mkeyw   'Baud',baudst
        mkeyw   'Bell',bellst
        mkeyw   'Block-check-type',blkset
        mkeyw   'Count',takectr
        mkeyw   'Debug',debst
        mkeyw   'Default-disk',cwdir
        mkeyw   'Delay',setdely
        mkeyw   'Destination',desset
        mkeyw   'Display',disply
        mkeyw   'Dump',setdmp
        mkeyw   'End-of-Line',eolset
        mkeyw   'EOF',seteof
        mkeyw   'Errorlevel',seterl
        mkeyw   'Escape',escset
        mkeyw   'Flow-control',floset
        mkeyw   'Handshake',hndset
        mkeyw   'Incomplete',abfset
        mkeyw   'Input',inpset
        mkeyw   'Key',setkey
        mkeyw   'Local-echo',lcal
        mkeyw   'Mode-line',modl
        mkeyw   'Parity',setpar
        mkeyw   'Port',coms
        mkeyw   'Prompt',promset
        mkeyw   'Receive',recset
        mkeyw   'Remote',remset
        mkeyw   'Retry',retryset
        mkeyw   'Send',sendset
        mkeyw   'Server',setsrv
        mkeyw   'Speed',baudst
        mkeyw   'Take-echo',takset
        mkeyw   'Terminal',vts
        mkeyw   'Timer',timset
        mkeyw   'Translation',setrx
        mkeyw   'Warning',filwar


seoftab db      2
        mkeyw   'Ctrl-Z',1
        mkeyw   'NoCtrl-Z',0

stsrtb  db      8                               ; Number of options
        mkeyw   'Packet-length',srpack
        mkeyw   'Padchar',srpad
        mkeyw   'Padding',srnpd
        mkeyw   'Pause',srpaus
        mkeyw   'Start-of-packet',srsoh
        mkeyw   'Quote',srquo
        mkeyw   'End-of-Line',sreol
        mkeyw   'Timeout',srtim

ontab   db      2
        mkeyw   'off',0
        mkeyw   'on',1

modtab  db      3                               ; Mode line status
        mkeyw   'off',0
        mkeyw   'on',1
        mkeyw   'on (owned by host)',2


destab  db      3
        mkeyw   'Disk',1
        mkeyw   'Printer',0
        mkeyw   'Screen',2

distab  db      5                       ; Set Display mode
        mkeyw   '7-bit',7               ; controls bit d8bit in flags.remflg
        mkeyw   '8-bit',8               ; sets d8bit
        mkeyw   'Quiet',dquiet          ; values defined in header file
        mkeyw   'Regular',dregular
        mkeyw   'Serial',dserial

dissta  db      6                       ; Status of Display mode [jrd]
        mkeyw   'Quiet, 7-bit',dquiet
        mkeyw   'Regular, 7-bit',dregular
        mkeyw   'Serial, 7-bit',dserial
        mkeyw   'Quiet, 8-bit',dquiet+d8bit
        mkeyw   'Regular, 8-bit',dregular+d8bit
        mkeyw   'Serial, 8-bit',dserial+d8bit

; What type of block check to use
blktab  db      3
        mkeyw   '1-character-checksum',1
        mkeyw   '2-character-checksum',2
        mkeyw   '3-character-CRC-CCITT',3

; If abort when receiving files, can keep what we have or discard

abftab  db      2
        mkeyw   'Discard',1
        mkeyw   'Keep',0

partab  db      5
        mkeyw   'none',PARNON
        mkeyw   'even',PAREVN
        mkeyw   'odd',PARODD
        mkeyw   'mark',PARMRK
        mkeyw   'space',PARSPC

flotab  db      2
        mkeyw   'none',flonon
        mkeyw   'xon/xoff',floxon

hndtab  db      8
        mkeyw   'none',0
        mkeyw   'bell',bell
        mkeyw   'cr',cr
        mkeyw   'esc',escape
        mkeyw   'lf',lf
        mkeyw   'xoff',xoff
        mkeyw   'xon',xon
        mkeyw   'code',0ffh             ; allow general numerial code

inptab  db      4                               ; Scripts. Set Input
        mkeyw   'Case',inpcas                   ;[jrs]
        mkeyw   'Default-timeout',inptmo        ;[jrs]
        mkeyw   'Echo',inpeco                   ;[jrs]
        mkeyw   'Timeout-action',inpact         ;[jrs]

inactb  db      2                               ; Set Input Timeout Action
        mkeyw   'Proceed',0                     ;[jrs]
        mkeyw   'Quit',1                        ;[jrs]

incstb  db      2                               ;[jrs] Set Input Case
        mkeyw   'Ignore',0dfh                   ;[jrs]
        mkeyw   'Observe',0ffh                  ;[jrs]


bdtab   db      18                      ; Baud rate table
        mkeyw   '45.5',b00455
        mkeyw   '50',b0050
        mkeyw   '75',b0075
        mkeyw   '110',b0110
        mkeyw   '134.5',b01345
        mkeyw   '150',b0150
        mkeyw   '300',b0300
        mkeyw   '600',b0600
        mkeyw   '1200',b1200
        mkeyw   '1800',b1800
        mkeyw   '2000',b2000
        mkeyw   '2400',b2400
        mkeyw   '4800',b4800
        mkeyw   '9600',b9600
        mkeyw   '19200',b19200
        mkeyw   '38400',b38400
        mkeyw   '57600',b57600
        mkeyw   '115200',b115200

debtab  db      4                       ; Set Debug command
        mkeyw   'Off',0
        mkeyw   'On',logpkt+logses
        mkeyw   'Packets',logpkt
        mkeyw   'Session',logses

logtab  db      3                       ; LOG command
        mkeyw   'Packets',logpkt
        mkeyw   'Session',logses
        mkeyw   'Transaction',logtrn

logsta  db      8                       ; Log Status table
        mkeyw   'off',logoff            ; suspended or no logging
        mkeyw   'Packet',logpkt
        mkeyw   'Session',logses
        mkeyw   'Packet+Session',logpkt+logses
        mkeyw   'Transaction',logtrn
        mkeyw   'Packet+Transaction',logpkt+logtrn
        mkeyw   'Session+Transaction',logses+logtrn
        mkeyw   'Packet+Session+Transaction',logpkt+logses+logtrn

srvdetab db     12                      ; Server Enable/Disable list
        mkeyw   'All',01ffh
        mkeyw   'CD',cwdflg
        mkeyw   'CWD',cwdflg
        mkeyw   'Delete',delflg
        mkeyw   'Dir',dirflg
        mkeyw   'Finish',finflg
        mkeyw   'Get',getsflg
        mkeyw   'Host',hostflg
        mkeyw   'Message',sndflg
        mkeyw   'Space',spcflg
        mkeyw   'Type',typflg
        mkeyw   'Tek4010',tekxflg       ; for automatic Tektronix invokation

endistab db     2                       ; Server ENABLE/DISABLE status
        mkeyw   'enabled',0
        mkeyw   'disabled',1

trnstab db      1                       ; Set Translation table
        mkeyw   'Input',1

; MACRO DATA STRUCTURES mcctab and macbuf
mcctab  db      1                       ; macro name table, one initially
        mkeyw   'IBM',ibmmac            ; offset of definition string (7 bytes)
        db      (macmax*10 - 7) dup (?) ; room for rest of macro names
mcclen  equ     $-mcctab                ; length of mcctab

mccptr  dw      mcctab + 8              ; ptr to first free byte in mcctab

macbuf  equ     this byte               ; buffer of macro strings
ibmmac  db      ibmlen                  ; startup IBM macro definition
        db      'set timer on',cr,'set parity mark',cr
        db      'set local-echo on',cr,'set handshake xon',cr
        db      'set flow none',cr
ibmlen  equ     $-ibmmac-1
        db      (macmax*60 -ibmlen-1) dup (?) ; space for additonal macro defs
maclen  equ     $ - macbuf              ; length of macbuf

macptr  dw      macbuf+ibmlen+1         ; ptr to first free byte in macbuf
; END OF MACRO DATA STRUCTURES

shom9m1 db      cr,lf,' Free space (bytes) for names: $'
shom9m2 db      ', for definitions: $'
shom9m3 db      cr,lf,' No macro(s)$'
shom9m4 db      '<cr>$'

sttab   stent   <baudprt>                               ; STATUS
        stent   <srchkw,vtemst,termtb,flags.vtflg>      ; terminal emulator
        stent   <srchkw,portst,comptab,flags.comflg>
        stent   <srchkw,modst,modtab,flags.modflg>
        stent   <srchkw,parmsg,partab,parflg,portval>
        stent   <prsnd, sndmsg>
        stent   <onoff,locst,,ecoflg,portval>
        stent   <stnum,stimst,,dtrans.stime>
        stent   <msg2,flost,floxmsg,floflg,portval>
        stent   <onechr,ssohst,,trans.ssoh>
        stent   <prhnd>
        stent   <stlnum,spakst,,trans.slongp>
        stent   <drnum,diskst,,curdsk>
        stent   <stnum,snpdst,,dtrans.spad>
        stent   <srchkw,destst,destab,flags.destflg>
        stent   <onechr,sqcst,,trans.rquote>
        stent   <onoff,flwon,,flags.flwflg>
        stent   <stnum,rtimst,,trans.rtime>
        stent   <msg2,abfkst,abfdst,flags.abfflg>
        stent   <onechr,rsohst,,trans.rsoh>
        stent   <srchkw,eofmsg,seoftab,flags.eofcz>
        stent   <stlnum,rpakst,,trans.rlongp>
        stent   <msg2,beloff,belon,flags.belflg>
        stent   <stnum,rnpdst,,trans.rpad>
        stent   <srchkw,capmsg,logsta,flags.capflg>
        stent   <onechr,rqcst,,dtrans.squote>
        stent   <onoff,timmsg,,flags.timflg>
        stent   <preol,meolst>
        stent   <srchkw,debon,logsta,flags.debug>
        stent   <stnum,retrymsg,,maxtry>
        stent   <onechr,escmes,,trans.escchr>
        stent   <srchkw,blokst,blktab,trans.chklen>
        stent   <srchkw,dispst,dissta,flags.remflg>
        stent   <pasz,dmpmsg2,offset dmpname>
        stent   <vtstat>
        dw      0                               ; end of table
stcom   stent   <srchkw,portst,comptab,flags.comflg>    ; SHOW COMMS
        stent   <baudprt>
        stent   <onoff,locst,,ecoflg,portval>
        stent   <srchkw,parmsg,partab,parflg,portval>
        stent   <prhnd>
        stent   <msg2,flost,floxmsg,floflg,portval>
        stent   <srchkw,dispst,dissta,flags.remflg>
        stent   <srchkw,debon,logsta,flags.debug>
        dw      0
stfile  stent   <drnum,diskst,,curdsk>                  ; SHOW FILE
        stent   <msg2,abfkst,abfdst,flags.abfflg>
        stent   <srchkw,destst,destab,flags.destflg>
        stent   <onoff,flwon,,flags.flwflg>
        stent   <srchkw,eofmsg,seoftab,flags.eofcz>
        stent   <onoff,takon,,flags.takflg>
        stent   <srchkw,dispst,dissta,flags.remflg>
        stent   <onoff,atton,,flags.attflg>
        dw      0
stlog   stent   <stmsg,logmsg>                          ; SHOW LOG
        stent   <srchkw,capmsg,logsta,flags.capflg>
        stent   <stmsg,spaces>
        stent   <pasz,lsesmsg,offset lsesnam>
        stent   <stmsg,spaces>
        stent   <pasz,lpktmsg,offset lpktnam>
        stent   <stmsg,spaces>
        stent   <pasz,ltramsg,offset ltranam>
        stent   <stmsg,spaces>
        stent   <pasz,dmpmsg,offset dmpname>
        dw      0

stpro   stent   <stlnum,spakst,,trans.slongp>           ; SHOW PROTOCOL
        stent   <stlnum,rpakst,,trans.rlongp>
        stent   <stnum,stimst,,dtrans.stime>
        stent   <stnum,rtimst,,trans.rtime>
        stent   <stnum,snpdst,,dtrans.spad>
        stent   <stnum,rnpdst,,trans.rpad>
        stent   <onechr,spadst,,dtrans.spadch>
        stent   <onechr,spadst,,trans.rpadch>
        stent   <onechr,ssohst,,trans.ssoh>
        stent   <onechr,rsohst,,trans.rsoh>
        stent   <onechr,sqcst,,dtrans.squote>
        stent   <onechr,rqcst,,trans.rquote>
        stent   <preol,meolst>
        stent   <stnum,retrymsg,,maxtry>
        stent   <prsnd,sndmsg>
        stent   <srchkw,blokst,blktab,trans.chklen>
        stent   <onoff,atton,,flags.attflg>
        stent   <prhnd>
        stent   <onoff,timmsg,,flags.timflg>
        stent   <srchkw,capmsg,logsta,flags.capflg>
        stent   <srchkw,debon,logsta,flags.debug>
        dw      0

stscpt  stent   <stmsg,scpmsg>                          ; SHOW SCRIPT
        stent   <onoff,sechmsg,,script.inecho>
        stent   <srchkw,scasmsg,incstb,script.incasv>
        stent   <stlnum,stmo1msg,,script.indfto>
        stent   <srchkw,stmo2msg,inactb,script.inactv>
        stent   <stalr,stalrmsg>
        stent   <stnum,sterlmsg,,errlev>
        stent   <stcnt,stcntmsg>
        dw      0
stserv  stent   <stmsg,servmsg>                         ; SHOW SERVER
        stent   <srchkb,scwdmsg,endistab,cwdflg,denyflg>
        stent   <srchkb,shstmsg,endistab,hostflg,denyflg>
        stent   <srchkb,sdelmsg,endistab,delflg,denyflg>
        stent   <srchkb,ssndmsg,endistab,sndflg,denyflg>
        stent   <srchkb,sdirmsg,endistab,dirflg,denyflg>
        stent   <srchkb,sspcmsg,endistab,spcflg,denyflg>
        stent   <srchkb,sfinmsg,endistab,finflg,denyflg>
        stent   <srchkb,stypmsg,endistab,typflg,denyflg>
        stent   <srchkb,sgetmsg,endistab,getsflg,denyflg>
        dw      0
stserv2 stent   <stnum,srvmsg,,srvtmo>
        dw      0
stterm  stent   <srchkw,vtemst,termtb,flags.vtflg>      ; SHOW TERMINAL
        stent   <srchkb,stekmsg,endistab,tekxflg,denyflg>
        stent   <onechr,escmes,,trans.escchr>
        stent   <srchkw,modst,modtab,flags.modflg>
        stent   <vtstat>
        dw      0
datas   ends

if1
        %out [End of pass 1]
else
        %out [End of assembly]
endif
        end