home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / extra / nyenhuis3.arc / MSSSET.ASM < prev    next >
Assembly Source File  |  1990-01-15  |  75KB  |  2,447 lines

  1.     NAME    mssset
  2. ; File MSSSET.ASM
  3.     include mssdef.h
  4. ; edit history:
  5. ; Last edit 15 Jan 1990
  6.  
  7.     public setcom, prmptr, dodef, setcpt, docom, stkadr, rdbuf
  8.     public setrx, rxtable, srvdsa, srvena, mcctab, takopen, takclos, ask
  9.     public askq, assign, initibm, mccptr, setinpbuf, setrollb, npages
  10.     public setchtab, xfchtab, xftyptab
  11.  
  12. braceop    equ    7bh        ; opening curly brace
  13. bracecl    equ    7dh        ; closing curly brace
  14.  
  15. maketab    MACRO            ; Assembler Macro to make rxtable [jrd]
  16. cnt = 0
  17.     rept 256
  18.     db    cnt        ; initialize table to 0 .. 255
  19. cnt = cnt + 1
  20.     endm
  21.     db    0        ; table off (0) or on (1) indicator
  22. ENDM
  23.  
  24. data     segment
  25.     extrn    comand:byte, flags:byte, trans:byte, takadr:word, taklev:byte
  26.     extrn    portval:word, dtrans:byte, spause:byte
  27.     extrn    filtst:byte, maxtry:byte, script:byte, denyflg:word
  28.     extrn    sloghnd:word, ploghnd:word, tloghnd:word
  29.     extrn    decbuf:byte, kstatus:word, errlev:byte, srvtmo:byte
  30.     extrn    luser:byte, lpass:byte, partab:byte, destab:byte, blktab:byte
  31.     extrn    seoftab:byte, dmpname:byte, lsesnam:byte, lpktnam:byte
  32.     extrn    ltranam:byte, incstb:byte, inactb:byte, rxoffmsg:byte
  33.     extrn    rxonmsg:byte, scpbuflen:word
  34.  
  35. rxtable    equ THIS BYTE        ; build 256 byte Translation Input table
  36.     maketab            ; table rxtable is used by Connect mode
  37.  
  38. kerm    db    'MS-Kermit>',0        ; default asciiz prompt
  39. prm    db    60 dup (0)        ; buffer for new prompt
  40. rdbuf    db    255 dup (?)        ; work space; room for macro def
  41.                     ;  and for Status display line
  42.  
  43. stflg    db    0        ; Says if setting SEND or RECEIVE parameter
  44. ermes1    db    cr,lf,'?Too many macro names$'
  45. ermes2    db    cr,lf,bell,'?No room for Take file buffer or Macro definition'
  46.     db    cr,lf,bell,'$'
  47. ermes4    db    cr,lf,'?Too many active Take files and Macros',cr,lf, bell,'$'
  48. ermes5    db    cr,lf,'?Not implemented$'
  49. ermes6    db    cr,lf,'?More parameters are needed$'
  50. errcap    db    cr,lf,'?Unable to open that file$'
  51. erropn    db    cr,lf,'?Log file is already open$'
  52. askhlp1    db    'Variable name  then  prompt string$'
  53. askhlp2    db    'Prompt string$'
  54. askhlp3    db    'Enter a line of text$'
  55. filhlp    db    ' Output filename for the log$'
  56. dishlp    db    cr,lf,' Quiet (no screen writing), Regular (normal),'
  57.     db    ' Serial (non-formatted screen)'
  58.     db    cr,lf,' and/or 7-BIT (default) or 8-BIT wide characters.$'
  59. remhlp    db    cr,lf,' OFF to show file transfer display,'
  60.     db    ' ON for quiet screen$'
  61. macmsg    db    ' Specify macro name followed by body of macro, on same line$'
  62. prmmsg    db    cr,lf
  63.     db    ' Enter new prompt string or nothing to regain regular prompt.'
  64.     db    cr,lf,' Use \123 notation for special chars (Escape is \27)$'
  65.  
  66. srxhlp1    db    cr,lf,' Enter   code for received byte   code for'
  67.     db    ' local byte ',cr,lf,' use ascii characters themselves or'
  68.     db    cr,lf,' numerical equivalents of  \nnn  decimal'
  69.     db    ' or \Onnn  octal or \Xnnn  hexadecimal',cr,lf
  70.     db    ' or keywords  ON  or  OFF  (translation is initially off)'
  71.     db    cr,lf,'$'
  72. badrx    db    cr,lf,'?Expected ON, OFF, or \nnn$'
  73.  
  74. takchlp    db    cr,lf,'Value 0 to 65535 for COUNT in script IF COUNT command$'
  75. takcerr    db    cr,lf,'?Note: command is valid only in Take files and Macros$'
  76.  
  77. dmpdefnam db    'Kermit.scn',0        ; asciiz default screen dump filename
  78. nummsg1 db    cr,lf,'?Use a number between $'
  79. nummsg2    db    ' and $'
  80. srvthlp    db    'seconds, 0-255, waiting for a transaction$'
  81. unkchhlp db    cr,lf,' Disposition of files arriving with unknown'
  82.     db    ' character sets:',cr,lf,'  Keep (default), Cancel$'
  83. winhelp    db    cr,lf,'Number of sliding window slots 1 (no windowing) to 31.'
  84.     db    cr,lf,'This also subdivides the 2000 byte main packet buffer'
  85.     db    cr,lf,'and may reduce the Send and Receive packet lengths.$'
  86. ctlhlp    db    ' Decimal number between 0 and 31$'
  87. dmphlp    db    ' Filename to hold screen dumps$'
  88. erlhlp    db    ' Decimal number between 0 and 255$'
  89. pakerr    db    cr,lf,'?Choose a decimal number '
  90.     db    'from 20 to 94 (normal) or to 2000 (long)$'
  91. pakhlp    db    cr,lf,'Decimal number between 20 and 94 (normal) or '
  92.     db    '2000 (long)$'
  93. padhlp    db    cr,lf,' Decimal number between 0 and 31 or 127$'
  94. pauhlp    db    ' Decimal number between 0 and 127$'
  95. quohlp    db    ' Decimal number between 33 and 126$'
  96. retryhlp db    ' Decimal number between 1 and 63$'
  97. luserh    db    cr,lf,'Username Password from remote Kermit (0-16 chars each)$'
  98. lpassh    db    cr,lf,'Password from remote Kermit (0-16 chars,'
  99.     db    ' spaces allowed)$'
  100. timhlp    db    ' Decimal number between 0 and 94$'
  101. delyhlp    db    ' Delay seconds before sending file (0-63)$'
  102. eschlp    db    cr,lf,'Press literal control keys (ex: Control ]) or'
  103.     db    ' enter in \nnn numerical form$'
  104. escerr    db    cr,lf,'?Not a control code$'
  105. hnd1hlp    db    cr,lf,'XON (\17), XOFF (\19), CR (\13), LF (\10), BELL (\7),'
  106.     DB    ' ESC (\27), NONE (\0)'
  107.     db    cr,lf,' or "CODE" followed by decimal number$' 
  108. intoms    db    'number of seconds to wait before timeout',cr,lf,'$'
  109. loghlp    db    cr,lf
  110.     db     ' PACKET - during file transfers (to default file PACKET.LOG)'
  111.     db    cr,lf
  112.     db     ' SESSION - during Connect mode  (to default file SESSION.LOG)'
  113.     db    cr,lf
  114.     db     ' TRANSACTION - files transfers (to default file TRANSACT.LOG)'
  115.     db    cr,lf,'  followed by an optional filename for the log.$'
  116. debhlp    db    cr,lf,' PACKETS - during file transfers'    ; Debugging
  117.     db    cr,lf,' SESSION - during Connect mode'
  118.     db    cr,lf,' ON - both packets and session'
  119.     db    cr,lf,' OFF - turns off all debugging$'
  120. dohlp    db    cr,lf,'definitions of variables (\%n), or press ENTER key$'
  121.  
  122. sdshlp    db    cr,lf,'DISABLE or ENABLE access to selected Server commands:'
  123.     db    cr,lf
  124.     db    ' CD/CWD, DEL, DIR, FINISH (includes BYE & LOGOUT), GET,'
  125.     db    ' HOST, KERMIT, LOGIN,',cr,lf
  126.     db    ' SEND, SPACE, TYPE, and ALL.$'
  127.  
  128. xfchhlp    db    cr,lf,' Which character set to put on the wire during file'
  129.     db    ' transfers:',cr,lf
  130.     db    '  TRANSPARENT (regular PC codes)',cr,lf
  131.     db    '  LATIN1 (ISO 8859-1)$'
  132. xfilhlp    db    'NONE, SPACE, or filler character$'
  133. xpmthlp db    'Host echo char acting as prompt, \1-\255$'
  134.  
  135. srvtab    db    2            ; SET SERVER table
  136.     mkeyw    'Login',1
  137.     mkeyw    'Timeout',2
  138.  
  139. sethlp    db    cr,lf
  140.     db    '  Alarm    sec from now or HH:MM:SS  '
  141.     db    '  Local-echo        on/off'
  142.     db    cr,lf
  143.     db    '  Attributes packets on/off          '
  144.     db    '  Log kind  opt filename'
  145.     db    cr,lf
  146.     db    '  Bell    on/off    at end of xfers  '
  147.     db    '  Mode-line         on/off'
  148.     db    cr,lf
  149.     db    '  Block-check-type  checksum/CRC     '
  150.     db    '  Parity    even/odd/mark/space/none'
  151.     db    cr,lf
  152.     db    '  COUNT   number    a loop counter   '
  153.     db    '  Port for i/o      1/2/COM1/COM2/etc'
  154.     db    cr,lf
  155.     db    '  Debug   on/off    display packets  '
  156.     db    '  Prompt  string   (new Kermit prompt)'
  157.     db    cr,lf
  158.     db    '  Default-disk                       '
  159.     db    '  Receive parameter  many things'
  160.     db    cr,lf
  161.     db    '  Delay   secs  before Sending file  '
  162.     db    '  Remote    on/off  show xfer counts?'
  163.     db    cr,lf
  164.     db    '  Destination   Disk/Screen/Printer  '
  165.     db    '  Retry limit for packet send/receive'
  166.     db    cr,lf
  167.     db    '  Display quiet/reg/serial show cnts?'
  168.     db    '  Send parameter    many things'
  169.     db    cr,lf
  170.     db    '  Dump filespec     screen to disk   '
  171.     db    '  Server parameter'
  172.     db    cr,lf
  173.     db    '  Duplex            half or full     '
  174.     db      '  Speed or Baud     many speeds'    
  175.     db    cr,lf
  176.     db    '  EOF Ctrl-Z/NoCtrl-Z  ^Z ends file? '
  177.     db    '  Take-echo on/off  display commands?' 
  178.     db    cr,lf
  179.     db     '  End-of-line char  cr or whatever   '
  180.     db    '  Terminal none/H-19/VT52/VT102/VT320'
  181.     db    cr,lf
  182.     db    '  Errorlevel number   for DOS Batch  '
  183.     db    '     and many terminal setup parameters'
  184.     db    cr,lf
  185.     db      '  Escape char  ^]   or whatever      '
  186.     db    '  Timer     on/off  time packet waiting'
  187.     db    cr,lf
  188.     db    '  File (Character-set, Type, Warning)'
  189.     db    '  Translation IN  Connect mode rcv''d char'
  190.     db    cr,lf
  191.     db    '  Flow-control      xon-xoff or none '
  192.     db    '  Transfer Character-set (on wire) '
  193.     db    cr,lf
  194.     db    '  Handshake xon/xoff/cr/lf/bell/esc..'
  195.     db    '  Transmit  parameters, for scripts'
  196.     db    cr,lf
  197.     db    '  Incomplete file   keep/discard     '
  198.     db    '  Unknown-character-set (keep/cancel)'
  199.     db    cr,lf
  200.     db    '  Input timeout, etc  (for scripts)  '
  201.     db    '  Warning   on/off  if file renamed'
  202.     db    cr,lf
  203.     db    '  Key         key-ident   definition ' 
  204.     db    '  Windows  number of sliding window slots'
  205.     db    cr,lf,'$'
  206.  
  207. settab     db    44                    ; Set table
  208.     mkeyw    'Alarm',setalrm
  209.     mkeyw    'Attributes',setatt
  210.     mkeyw    'Baud',baudst
  211.     mkeyw    'Bell',bellst
  212.     mkeyw    'Block-check-type',blkset
  213.     mkeyw    'Count',takectr
  214.     mkeyw    'Debug',debst
  215.     mkeyw    'Default-disk',cwdir
  216.     mkeyw    'Delay',setdely
  217.     mkeyw    'Destination',desset
  218.     mkeyw    'Display',disply
  219.     mkeyw    'Dump',setdmp
  220.     mkeyw    'Duplex',setdup
  221.     mkeyw    'End-of-Line',eolset
  222.     mkeyw    'EOF',seteof
  223.     mkeyw    'Errorlevel',seterl
  224.     mkeyw    'Escape',escset
  225.     mkeyw    'File',setfile
  226.     mkeyw    'Flow-control',floset
  227.     mkeyw    'Handshake',hndset
  228.     mkeyw    'Incomplete',abfset
  229.     mkeyw    'Input',inpset
  230.     mkeyw    'Key',setkey
  231.     mkeyw    'Local-echo',lcal
  232.     mkeyw    'Log',setcpt            ; same as log command
  233.     mkeyw    'Mode-line',modl
  234.     mkeyw    'Parity',setpar
  235.     mkeyw    'Port',coms
  236.     mkeyw    'Prompt',promset
  237.     mkeyw    'Receive',recset
  238.     mkeyw    'Remote',remset
  239.     mkeyw    'Retry',retryset
  240.     mkeyw    'Send',sendset
  241.     mkeyw    'Server',setsrv
  242.     mkeyw    'Speed',baudst
  243.     mkeyw    'Take-echo',takset
  244.     mkeyw    'Terminal',vts
  245.     mkeyw    'Timer',timset
  246.     mkeyw    'Transfer',sxfer
  247.     mkeyw    'Translation',setrx
  248.     mkeyw    'Transmit',setxmit
  249.     mkeyw    'Unknown-character-set',unkchset
  250.     mkeyw    'Warning',filwar
  251.     mkeyw    'Windows',winset
  252.  
  253. setfitab db    3            ; Set File command table
  254.     mkeyw    'Character-Set',1
  255.     mkeyw    'Type',2
  256.     mkeyw    'Warning',0
  257.  
  258. setchtab db    5            ; Set File Character-Set table
  259.     mkeyw    'CP437',437        ; hardware default Code Page
  260.     mkeyw    'CP850',850        ; Multilingual CP
  261.     mkeyw    'CP860',860        ; Portuguese CP
  262.     mkeyw    'CP863',863        ; French Canadian CP
  263.     mkeyw    'CP865',865        ; Norwegian CP
  264. ;;    mkeyw    'User-defined',1    ; User loadable table
  265.  
  266. xfertab    db    1            ; SET TRANSFER table
  267.     mkeyw    'Character-set',0
  268.  
  269. xfchtab    db    2            ; SET TRANSFER CHARACTER-SET
  270.     mkeyw    'TRANSPARENT',0        ; no translation
  271.     mkeyw    'Latin1',1        ; ISO 8859-1, Latin-1
  272.  
  273. xftyptab db    2            ; SET FILE TYPE table
  274.     mkeyw    'Binary',1        ; Binary = as-is
  275.     mkeyw    'Text',0        ; Text = can change char sets
  276.  
  277. warntab    db    5            ; File Warning table
  278.     mkeyw    'Overwrite',1        ; overwrite
  279.     mkeyw    'Rename',0        ; rename
  280.     mkeyw    'No-supersede',4    ; discard
  281.     mkeyw    'on (rename)',0        ; old form
  282.     mkeyw    'off (overwrite)',1    ; old form
  283.  
  284. unkctab db    2            ; unknown character-set disposition
  285.     mkeyw    'Keep',0
  286.     mkeyw    'Cancel',1
  287.  
  288. atttab    db    6            ; SET ATTRIBUTES table
  289.     mkeyw    'Off',00ffh        ; all off
  290.     mkeyw    'On',10ffh        ; all on (high byte is on/off)
  291.     mkeyw    'Character-set',attchr    ; Character set
  292.     mkeyw    'Date-Time',attdate    ; Date and Time
  293.     mkeyw    'Length',attlen        ; Length
  294.     mkeyw    'Type',atttype        ; Type
  295.  
  296. stsrtb    db    8                ; Number of options
  297.     mkeyw    'Packet-length',srpack
  298.     mkeyw    'Padchar',srpad
  299.     mkeyw    'Padding',srnpd
  300.     mkeyw    'Pause',srpaus
  301.     mkeyw    'Start-of-packet',srsoh
  302.     mkeyw    'Quote',srquo
  303.     mkeyw    'End-of-packet',sreol
  304.     mkeyw    'Timeout',srtim
  305.  
  306. ontab    db    2
  307.     mkeyw    'off',0
  308.     mkeyw    'on',1
  309.  
  310. distab    db    5             ; Set Display mode
  311.     mkeyw    '7-bit',7        ; controls bit d8bit in flags.remflg
  312.     mkeyw    '8-bit',8        ; sets d8bit
  313.     mkeyw    'Quiet',dquiet        ; values defined in header file
  314.     mkeyw    'Regular',dregular
  315.     mkeyw    'Serial',dserial
  316.  
  317. ; If abort when receiving files, can keep what we have or discard
  318.  
  319. abftab    db    2
  320.     mkeyw    'Discard',1
  321.     mkeyw    'Keep',0
  322.  
  323. flotab    db    2
  324.     mkeyw    'none',flonon
  325.     mkeyw    'xon/xoff',floxon
  326.  
  327. hndtab    db    8
  328.     mkeyw    'none',0
  329.     mkeyw    'bell',bell
  330.     mkeyw    'cr',cr
  331.     mkeyw    'esc',escape
  332.     mkeyw    'lf',lf
  333.     mkeyw    'xoff',xoff
  334.     mkeyw    'xon',xon
  335.     mkeyw    'code',0ffh        ; allow general numerial code
  336.  
  337. duptab    db    2            ; SET DUPLEX table
  338.     mkeyw    'full',0
  339.     mkeyw    'half',1
  340.  
  341. inptab    db    4                ; Scripts. Set Input
  342.     mkeyw    'Case',inpcas            ;[jrs]
  343.     mkeyw    'Default-timeout',inptmo    ;[jrs]
  344.     mkeyw    'Echo',inpeco            ;[jrs]
  345.     mkeyw    'Timeout-action',inpact        ;[jrs]
  346.  
  347. xmitab    db    3            ; SET TRANSMIT table
  348.     mkeyw    'Fill-empty-line',0
  349.     mkeyw    'Line-Feeds-sent',1
  350.     mkeyw    'Prompt',2
  351.  
  352. debtab    db    4            ; Set Debug command
  353.     mkeyw    'Off',0
  354.     mkeyw    'On',logpkt+logses
  355.     mkeyw    'Packets',logpkt
  356.     mkeyw    'Session',logses
  357.  
  358. logtab    db    3            ; LOG command
  359.     mkeyw    'Packets',logpkt
  360.     mkeyw    'Session',logses
  361.     mkeyw    'Transaction',logtrn
  362.  
  363. srvdetab db    13            ; Server Enable/Disable list
  364.     mkeyw    'All',07ffh
  365.     mkeyw    'CD',cwdflg
  366.     mkeyw    'CWD',cwdflg
  367.     mkeyw    'Delete',delflg
  368.     mkeyw    'Dir',dirflg
  369.     mkeyw    'Finish',finflg
  370.     mkeyw    'Get',getsflg
  371.     mkeyw    'Host',hostflg
  372.     mkeyw    'Kermit',kerflg
  373.     mkeyw    'Login',pasflg
  374.     mkeyw    'Send',sndflg
  375.     mkeyw    'Space',spcflg
  376.     mkeyw    'Type',typflg
  377.  
  378. trnstab    db    2            ; Set Translation table
  379.     mkeyw    'Input',1
  380.     mkeyw    'Keyboard',2
  381.  
  382. ; MACRO DATA STRUCTURES mcctab
  383. mcclen    equ    macmax*10        ; length of mcctab
  384. mcctab    db    0            ; macro name table entries
  385.     db    mcclen dup (0)        ; room for macro structures
  386. ; END OF MACRO DATA STRUCTURES
  387.  
  388. ibmmac    db    'IBM '            ; startup IBM macro definition
  389.     db    'set timer on,set parity mark,set local-echo on,'
  390.     db    'set handshake xon,set flow none,',0    ; asciiz
  391.  
  392.     even
  393. prmptr    dw    kerm            ; pointer to prompt
  394. tempptr    dw    0            ; pointer into work buffer
  395. domacptr dw    0            ; pointer to DO MAC string
  396. min    dw    0 
  397. max    dw    0 
  398. numerr    dw    0
  399. numhlp    dw    0
  400. temp    dw    0
  401. temp1    dw    0            ; Temporary storage
  402. temp2    dw    0            ; Temporary storage
  403. temptc    db    4 dup (0)        ; temp quad, for takclos
  404. deftemp    dw    0
  405. stkadr    dw    0    ; non-zero if replacement keyboard xlator present
  406. mccptr    dw    mcctab             ; ptr to first free byte in mcctab
  407. macptr    dw    0            ; temp to hold segment of string
  408. npages    dw    10             ; # of pages of scrolling on each side
  409. data    ends
  410.  
  411. code    segment
  412.     extrn comnd:near, baudst:near, prompt:near, coms:near, cwdir:near
  413.     extrn makebuf:near, isfile:near, strlen:near, strcpy:near, cnvlin:near
  414.     extrn katoi:near, decout:near, vts:near
  415.     extrn setalrm:near
  416.  
  417.     assume    cs:code, ds:data, es:nothing
  418.  
  419. ; DO defined macro command
  420. ; DO macname variable variable   also defines variables \%1, \%2, ...\%9
  421. DOCOM    PROC    NEAR
  422.     mov    dx,offset mcctab    ; table of macro defs
  423.     xor    bx,bx            ; help is table
  424.     mov    ah,cmkey        ; get key word (macro name)
  425.     call    comnd            ; get pointer to keyword structure
  426.     jnc    docom1            ; nc = success, bx = 16 bit data
  427.     ret                ; failure
  428. docom1:    mov    domacptr,bx        ; segment of definition string
  429.     mov    comand.cmquiet,0    ; permit command echoing
  430.     mov    bx,offset decbuf    ; point to borrowed work buffer
  431.     mov    word ptr[bx],0        ; clear buffer
  432.     mov    dx,offset dohlp        ; help
  433.     mov    comand.cmblen,length rdbuf ; length of analysis buffer
  434.     mov    ah,cmline        ; get line of text, if any
  435.     call    comnd
  436.     jnc    docom2            ; nc = success
  437.     ret                ; failure
  438. docom2:    mov    al,ah
  439.     xor    ah,ah
  440.     mov    deftemp,ax        ; save byte count of command args
  441.     mov    max,1            ; temp for counting 1 + number args
  442.     or    al,al            ; anything given?
  443.     jz    docom4            ; z = no, just do the macro
  444.     mov    word ptr rdbuf+3,' 1'    ; number of first variable
  445. docom3:    mov    rdbuf,0            ; clear length field, install \%x name
  446.     mov    word ptr rdbuf+1,'%\'    ; start with '\%1 '
  447.     mov    word ptr rdbuf+5,0    ; clear text field
  448.     mov    tempptr,offset rdbuf+5    ; pointer to location of found word
  449.     mov    ch,0            ; make cx = 1 - 9
  450.     mov    cl,rdbuf+3        ; cx = word # of interest, for getwrd
  451.     sub    cl,'0'            ; remove ascii bias
  452.     mov    si,offset decbuf    ; source = work buffer (borrowed)
  453.     call    getwrd            ; get CX-th word from  work buf (1-9)
  454.     cmp    deftemp,0        ; length of word, was it found?
  455.     je    docom4            ; e = no, end variable definition part
  456.     add    deftemp,4        ; count '\%n ' in command line length
  457.     inc    max            ; one more argument
  458.     mov    cx,deftemp        ; command length for dodecom
  459.     call    dodecom            ; add keyword+def using DEF MAC below
  460.     inc    rdbuf+3            ; inc number of variable in '\%n '
  461.     cmp    rdbuf+3,'9'
  462.     jbe    docom3            ; do '1' through '9', if available
  463.  
  464.                     ; DO the macro itself
  465. docom4:    cmp    taklev,maxtak        ; room in take level?
  466.     jl    docom5            ; l = yes, continue
  467.     mov    dx,offset ermes4    ; else complain
  468.     jmp    reterr
  469. docom5:    inc    taklev            ; increment take level
  470.     add    takadr,size takinfo    ; create a Take macro
  471.     mov    bx,takadr        ; point to current structure
  472.     push    es
  473.     mov    es,domacptr        ; segment of macro definition string
  474.     mov    [bx].takbuf,es        ; remember in Take structure
  475.     mov    cl,es:byte ptr [0]    ; length of definition
  476.     pop    es
  477.     xor    ch,ch            ; clear high byte
  478.     mov    [bx].takcnt,cx        ; # of chars in buffer
  479.     mov    [bx].taktyp,0ffh    ; flag as a macro
  480.     mov    [bx].takptr,1        ; point to beginning of def text
  481.     mov    cx,max            ; 1 + number of arguments
  482.     mov    [bx].takargc,cx
  483.     clc                ; success
  484.     ret
  485. DOCOM    ENDP
  486.  
  487. ; Extract CX-th word (cx = 1-9) from buffer (DI). Enter with si = source
  488. ; string and tempptr pointing at destination. Returns deftemp (count) of
  489. ; transferred characters. Allow string in curly braces to exist as a word.
  490. ; Adjacent curly braced strings are separate "words":
  491. ;    {this is word-one}{this is word-two}word-three.
  492. ; All registers preserved.
  493. getwrd    proc    near
  494.     push    ax
  495.     push    cx
  496.     push    dx
  497.     push    si
  498.     push    di
  499.     push    es
  500.     push    ds
  501.     pop    es            ; set es to data segment
  502. getwr1:    push    cx            ; save word counter (1-9)
  503.     mov    deftemp,0        ; no bytes transferred yet
  504.     mov    di,tempptr        ; where to store word/string
  505.     mov    byte ptr [di],0        ; clear destination
  506.     mov    dx,si            ; start looking here in work buf
  507.     call    strlen            ; cx = remaining length of work buf
  508.     jcxz    getwr6            ; z = nothing there, quit
  509. getwr2:    lodsb
  510.     cmp    al,' '            ; skip leading whitespace
  511.     loope    getwr2
  512.     dec    si            ; return to break char
  513.                     ; Parse curly brace delimited string
  514.                     ; end with si after closing brace
  515.     mov    dl,0            ; assume "opening brace" is a null
  516.     mov    dh,' '            ; assume "closing brace" is a space
  517.     mov    cx,1            ; we are at brace level 1
  518.     cmp    byte ptr [si],braceop    ; starting with a real opening brace?
  519.     jne    getwr3            ; ne = no
  520.     inc    si            ; skip opening brace
  521.     mov    dl,braceop        ; opening brace (we count them up)
  522.     mov    dh,bracecl        ; closing brace (we count them down)
  523. getwr3:    cld                ; search forward
  524.     lodsb                ; read a char
  525.     stosb                ; store in output buffer
  526.     cmp    al,0            ; at end of text?
  527.     jne    getwr3a            ; ne = no
  528.     dec    si            ; stay at null terminator
  529.     dec    di
  530.     jmp    short getwr6        ; we are done with this "word"
  531. getwr3a:inc    deftemp            ; count copied char
  532.     cmp    al,dl            ; an opening brace?
  533.     jne    getwr4            ; ne = no
  534.     inc    cx            ; yes, increment brace level
  535.     jmp    short getwr3        ;  and continue scanning
  536.  
  537. getwr4:    cmp    al,dh            ; closing brace?
  538.     jne    getwr3            ; ne = no, continue scanning
  539.     dec    cx            ; yes, decrement brace level
  540.     cmp    byte ptr [si],0        ; have we just read the last char?
  541.     jne    getwr5            ; no, continue scanning
  542.     mov    cx,0            ; yes, this is the closing brace
  543. getwr5:    cmp    cx,0            ; at level 0?
  544.     jne    getwr3            ; ne = no, #opening <> #closing braces
  545.     mov    byte ptr [di-1],0    ; plant terminator on closing brace
  546.     dec    deftemp            ; do not count closing brace
  547. getwr6:    pop    cx            ; recover word counter
  548.     mov    byte ptr [di],0
  549.     jcxz    getwrx            ; just in case
  550.     loop    getwr1            ; do until desired word is copied
  551. getwrx:    pop    es
  552.     pop    di
  553.     pop    si
  554.     pop    dx
  555.     pop    cx
  556.     pop    ax
  557.     ret
  558. getwrd    endp
  559.  
  560. ; DEFINE and ASSIGN macro commands
  561. ; Data structures comments. Macro name is stored in table mcctab as if we
  562. ; had used macro mkeyw, such as       mkeyw 'mymac',offset my_definition.
  563. ; In detail:    db    length of name
  564. ;        db    'name'
  565. ;        db    '$'
  566. ;        dw    segment:0 of definition string
  567. ; Mcctab begins with a byte holding the number of macros in the table; one,
  568. ;  IBM, is established at assembly time. Mcctab is 10*macmax bytes long.
  569. ; Pointer mccptr holds the offset of the next free byte in mcctab.
  570. ; Definition strings are stored in individually allocated memory as
  571. ;        db    length of definition string below
  572. ;        db    'definition string'
  573. ; A new definition is read into buffer rdbuf+1, where byte rdbuf is reserved
  574. ;  to hold the length of the macro's name during intermediate processing.
  575. ; If the definition is absent then the macro is removed from the tables.
  576. ;
  577. ; ASSIGN is equivalent to DEFINE, except in the definition string substitution
  578. ; variable names are expanded to their definitions. This becomes a copy cmd.
  579. ; DEFINE does not expand substitution variables.
  580.  
  581. ASSIGN    PROC    NEAR
  582.     mov    temp,0            ; flag command as ASSIGN, vs DEFINE
  583.     jmp    dodefcom        ; common code
  584. ASSIGN    ENDP
  585.  
  586. DODEF    PROC    NEAR
  587.     mov    temp,1            ; flag command as DEFINE, vs ASSIGN
  588. DODEFCOM:
  589.     mov    comand.cmper,1        ; do not react to '\%' in macro name
  590.     mov    ah,cmword
  591.     mov    dx,offset rdbuf+1    ; buffer for macro name
  592.     mov    word ptr rdbuf,0
  593.     mov    bx,offset macmsg
  594.     call    comnd            ; get macro name
  595.     jnc    dodef1            ; nc = success
  596.     ret                ; failure
  597. dodef1:    cmp    ah,0            ; null entry?
  598.     jne    dodef2            ; ne = no
  599.     mov    dx,offset ermes6    ; more parameters needed
  600.     jmp    reterr
  601.  
  602. dodef2:    mov    bx,dx            ; updated pointer
  603.     mov    byte ptr [bx-1],' '    ; replace null with space separator
  604.     mov    word ptr [bx],0        ; terminator, in case no command
  605.     mov    ax,bx            ; stopping offset
  606.     sub    ax,offset rdbuf        ; ax = amount of buffer used
  607.     neg    ax
  608.     add    ax,length rdbuf-1
  609.     mov    comand.cmblen,al    ; our new buffer length
  610.     mov    ax,temp            ; get ASSIGN/DEFINE flag
  611.     mov    comand.cmper,al        ; react (DEF) to '\%' in definition
  612.     mov    ah,cmline        ; get a line of text
  613.     mov    dx,offset macmsg    ; help
  614.     call    comnd            ; get macro definition text
  615.     jnc    dodef3            ; nc = success
  616.     ret                ; failure
  617. dodef3:    sub    bx,offset rdbuf        ; length of command line
  618.     dec    bx            ; minus count byte
  619.     mov    cx,bx            ; save length of command line
  620. ;;    jmp    dodecom            ; common code below
  621. DODEF    ENDP
  622.  
  623. ; Make a macro table entry and allocate buffer space.
  624. ; Enter with rdbuf+1 et seq = <macro name><spaces><arg><spaces><arg> ...
  625. ; and CX = byte count of line, starting at rdbuf+1.
  626. ; Byte rdbuf+0 computed here as length of keyword.
  627. ; Allocates memory based on analyzed size of command line, returns memory
  628. ; segment in macptr and in AX. Returns carry set if failure.
  629. DODECOM    PROC    NEAR
  630.     push    si            ; macro name in rdbuf+1 et seq
  631.     push    di            ; cmd line length in deftemp
  632.     push    es
  633.     push    ds            ; address data segment
  634.     pop    es
  635.     mov    deftemp,cx        ; cmd line len, cx = running counter
  636.     mov    rdbuf,0            ; number of chars in keyword so far
  637.                     ; uppercase the keyword, look for end
  638.     mov    si,offset rdbuf+1    ; point at macro name itself
  639.     cld                ; strings go forward
  640. dode2:    lodsb                ; get a byte
  641.     cmp    al,'a'            ; map lower case to upper
  642.     jb    dode3
  643.     cmp    al,'z'
  644.     ja    dode3
  645.     sub    al,'a'-'A'
  646.     mov    [si-1],al        ; uppercase if necessary
  647. dode3:    inc    rdbuf            ; increment char count of keyword
  648.     cmp    al,' '            ; is this the break character?
  649.     loopne    dode2            ; no, loop thru rest of word
  650.     jne    dode4            ; ne = did not end with break char
  651.     dec    rdbuf            ; yes, don't count in length
  652. dode4:    mov    di,offset rdbuf        ; point at mac name length byte
  653.     call    remtab            ; remove any duplicate keyword
  654.     jcxz    dode6            ; cx = 0 means no keyword
  655.                     ; check for free space for keyword
  656.     mov    al,rdbuf        ; keyword text length
  657.     add    al,4            ; plus overhead bytes
  658.     xor    ah,ah
  659.     add    ax,mccptr        ; add to free space pointer
  660.     cmp    ax,offset mcctab+mcclen ; enough room for name?
  661.     jb    dode5            ; b = yes
  662.     mov    dx,offset ermes1    ; too many macro names
  663.     pop    es
  664.     pop    di
  665.     pop    si
  666.     jmp    reterr
  667.  
  668. dode5:    mov    di,si            ; si = definition source address
  669.     add    di,cx            ; length of string
  670.     std
  671.     mov    al,' '            ; scan off trailing spaces
  672.     repe    scasb
  673.     add    di,2            ; backup to terminator slot
  674.     cld
  675.     mov    byte ptr [di],0        ; plant new terminator
  676.     mov    dx,si
  677.     call    strlen            ; get new length into cx
  678.     cld
  679.     mov    di,si            ; scan after keyword name
  680.     mov    al,' '            ; remove leading spaces in string
  681.     repe    scasb
  682.     jne    dode6            ; ne = have some text
  683.     pop    es            ; all spaces
  684.     pop    di
  685.     pop    si
  686.     clc                ; success
  687.     ret
  688. dode6:    dec    di            ; offset auto increment of rep
  689.     mov    dx,di            ; source of definition text
  690.     call    strlen            ; get length of string into cx
  691.     mov    deftemp,cx        ; remember it here
  692.                     ; install new keyword
  693.     jcxz    dode10            ; z = no def, exit now
  694.     mov    bx,cx            ; string length, in bytes
  695.     add    bx,15+1+1        ; count byte + null term + round up
  696.     mov    cl,4
  697.     shr    bx,cl            ; convert to paragraphs (divide by 16)
  698.     mov    cx,bx            ; remember desired paragraphs
  699.     mov    ah,alloc        ; allocate a memory block
  700.     int    dos
  701.     jc    dode12            ; c = error, not enough memory
  702.      cmp    bx,cx            ; obtained vs wanted
  703.     jae    dode7            ; ae = enough
  704.     mov    es,ax            ; allocated segment
  705.     mov    ah,freemem        ; free it again
  706.     int    dos
  707.     jmp    short dode12        ; quit here
  708.  
  709. dode7:    mov    macptr,ax        ; store new segment
  710.             ; copy definition into buffer, changing commas to CRs
  711.     mov    es,ax            ; segment of string
  712.     mov    di,0            ; offset of count byte
  713.     mov    cx,deftemp        ; length of definition string
  714.     mov    al,cl
  715.     cld
  716.     stosb                ; store length of string
  717. dode8:    lodsb                ; get a byte
  718.     cmp    al,','            ; comma?
  719.     jne    dode9            ; no, keep going
  720.     mov    al,cr            ; else replace with cr
  721. dode9:    stosb
  722.     loop    dode8            ; keep copying
  723.     mov    bx,offset mcctab    
  724.     mov    dx,offset rdbuf        ; count byte + name string
  725.     call    addtab
  726. dode10:    mov    ax,macptr        ; return buffer segment to caller
  727.     pop    es
  728.     pop    di
  729.     pop    si
  730.     clc                ; success
  731.     ret
  732. dode12:    pop    es            ; no memory, clean stack
  733.     pop    di
  734.     pop    si
  735.     mov    dx,offset ermes2    ; no room for definition
  736.     mov    ah,prstr
  737.     int    dos
  738.     stc
  739.     ret
  740. DODECOM    ENDP
  741.  
  742. ; ASK <variable or macro name> <prompt string>
  743. ; Defines indicated variable/macro with text from user at keyboard or pipe
  744. ; (but not from a Take/macro). Prompt string is required.
  745. ; ASKQ does the same, but does not echo user's response.
  746. ASKQ    PROC    NEAR
  747.     mov    deftemp,1        ; temp to flag as Quiet version
  748.     jmp    short ask0        ; do common code
  749. ASKQ    ENDP
  750.  
  751. ASK    PROC    NEAR
  752.     mov    deftemp,0        ; temp to flag as echoing version
  753. ask0:                    ; common code for ASK and ASKQ
  754.     mov    dx,offset rdbuf+1    ; point to work buffer
  755.     mov    word ptr rdbuf,0
  756.     mov    bx,offset askhlp1    ; help
  757.     mov    comand.cmper,1        ; do not expand variable name
  758.     mov    ah,cmword        ; get variable name
  759.     call    comnd
  760.     jnc    ask1            ; nc = success
  761.     ret                ; failure
  762. ask1:    cmp    ah,0            ; anything given?
  763.     jne    ask2            ; ne = yes
  764.     mov    dx,offset ermes6    ; more parameters needed
  765.     jmp    reterr
  766.  
  767. ask2:    xchg    ah,al
  768.     mov    ah,0
  769.     mov    bx,offset rdbuf+1    ; start of name
  770.     add    bx,ax            ; plus length of variable name
  771.     mov    byte ptr [bx],' '    ; put space separator after name
  772.     inc    ax            ; count space
  773.     mov    temp,ax            ; remember length here
  774.                     ; get ASK command prompt string
  775.     inc    bx            ; put prompt string here
  776.     mov    byte ptr [bx],0        ; safety terminator
  777.     mov    dx,offset askhlp2
  778.     mov    comand.cmblen,127    ; our buffer length
  779.     sub    comand.cmblen,al    ;  minus part used above
  780.     mov    ah,cmline        ; get prompt string
  781.     call    comnd
  782.     jnc    ask3            ; nc = success
  783.     ret                ; failure
  784. ask3:    cmp    ah,0            ; anything given?
  785.     jne    ask4            ; ne = yes
  786.     mov    dx,offset ermes6    ; more parameters needed
  787.     jmp    reterr
  788.  
  789. ask4:    mov    ax,takadr        ; we could be in a macro or Take file
  790.     mov    temp2,ax        ; save Take address
  791.     mov    al,taklev
  792.     mov    ah,0
  793.     mov    temp1,ax        ; and Take level
  794.     mov    dx,size takinfo        ; bytes for each current Take
  795.     mul    dx            ; times number of active Take/macros
  796.     sub    takadr,ax        ; clear Take address as if no
  797.     mov    taklev,0        ;  Take/macro were active so that
  798.                     ;  user input is from kbd or pipe
  799.     mov    word ptr [bx],0020h    ; printing terminator for prompt
  800.     mov    si,offset rdbuf+1
  801.     add    si,temp            ; prompt for input string
  802.     mov    di,si            ; convert in-place
  803.     call    cnvlin            ; convert backslash items
  804.     mov    dx,si            ; converted prompt string, asciiz
  805.      call    prompt            ; buf = <var name>< ><prompt string>
  806.     mov    bx,offset rdbuf+129    ; use this buffer for raw user input
  807.     mov    word ptr [bx],0        ; insert terminator
  808.     mov    dx,deftemp        ; get echo/quiet flag
  809.     mov    comand.cmquiet,dl    ; 0 if echoing
  810.     mov    dx,offset askhlp3    ; help for user input
  811.     mov    ah,cmline        ; read user's input string
  812.     call    comnd
  813.     mov    comand.cmquiet,0    ; permit echoing again
  814.     jc    ask9            ; exit now on ^C from user
  815.     mov    cl,ah            ; length of entry
  816.     mov    ch,0
  817.     mov    si,offset rdbuf+129    ; source string
  818.     mov    di,offset rdbuf+1    ; start of variable name
  819.     add    di,temp            ; di points to final user string
  820.     push    es            ; save es
  821.     push    ds
  822.     pop    es            ; set es to data segment
  823.     cld
  824.     jcxz    ask8            ; z = empty
  825. ask6:    lodsb                ; read original user string char
  826.     cmp    al,','            ; literal comma?
  827.     jne    ask7            ; ne = no
  828.     mov    ax,'{\'            ; yes. Replace literal comma
  829.     stosw                ;  with numerical equivalent \{44}
  830.     mov    ax,'44'            ;  to permit commas in macro def
  831.     stosw
  832.     add    temp,4
  833.     mov    al,'}'
  834. ask7:    stosb                ; store string character
  835.     inc    temp            ; length of <variable>< ><user string>
  836.     loop    ask6
  837. ask8:    xor    al,al            ; get null terminator
  838.     stosb                ; plant it
  839.     pop    es
  840.     mov    ax,temp            ; length of <variable>< ><user string>
  841.     mov    deftemp,ax        ; put here for dodecom usage
  842.     mov    ax,temp2
  843.     mov    takadr,ax        ; restore Take address
  844.     mov    ax,temp1
  845.     mov    taklev,al        ; restore Take level
  846.     mov    cx,deftemp        ; command length for dodecom
  847.     jmp    DODECOM            ; define the macro/variable and exit
  848.  
  849. ask9:    mov    ax,temp2        ; failure path
  850.     mov    takadr,ax        ; restore Take address
  851.     mov    ax,temp1
  852.     mov    taklev,al        ; restore Take level
  853.     stc                ; failure
  854.     ret                ; return command failure
  855. ASK    ENDP
  856.  
  857. ; Initialize macro IBM at Kermit startup time
  858. initibm    proc    near
  859.     mov    si,offset ibmmac    ; text of IBM macro
  860.     mov    di,offset rdbuf+1    ; where command lines go
  861.     call    strcpy            ; copy it there
  862.     mov    dx,di            ; get length of command line
  863.     call    strlen            ; set cx to length, for dodecom
  864.     jmp    dodecom            ; now define the macro
  865. initibm    endp
  866.  
  867. ; Open a disk based Take file buffer. Define macro named "<null>T<'taklev'>",
  868. ; in mcctab and allocate 128 byte uninitiated buffer for disk i/o. Leading null
  869. ; is to prevent user from employing the same name accidentally. Return seg
  870. ; of buffer in [takadr].takbuf and set [takadr].takptr to offset of first
  871. ; byte after leading count byte. Uses dodecom to make this macro.
  872. ; Return carry clear for success, carry set for failure.
  873.  
  874. TAKOPEN    PROC    NEAR
  875.     push    ax
  876.     push    bx
  877.     push    cx
  878.     push    dx
  879.     cmp    taklev,maxtak        ; room in take level?
  880.     jb    takope1            ; b = yes
  881.     mov    dx,offset ermes4    ; say too many Take files
  882.     mov    ah,prstr        ; display error message
  883.     int    dos
  884.     stc                ; set carry for failure
  885.     jmp    short takope2
  886.  
  887. takope1:mov    rdbuf,3            ; length of name, 3 bytes <null>Tn
  888.     mov    rdbuf+1,0
  889.     mov    rdbuf+2,'T'        ; name of <null>Tn
  890.     mov    al,taklev        ; Take level digit
  891.     inc    al            ; for what will be next Take level
  892.     add    al,'0'            ; add ascii bias
  893.     mov    rdbuf+3,al        ; last of the name
  894.     mov    rdbuf+4,' '        ; separate dummy definition
  895.     mov    cx,tbufsiz        ; fill with dummy non-blank data
  896.     push    cx            ; length of buffer, for dodecom
  897.     push    di
  898.     push    es            ; save es
  899.     push    ds            ; set es to data segment
  900.     pop    es
  901.     cld
  902.     mov    al,'.'            ; dummy fill pattern
  903.     mov    di,offset rdbuf+5    ; definition text starts here
  904.     rep    stosb            ; store the pattern
  905.     pop    es
  906.     pop    di
  907.     pop    cx            ; get command length again
  908.     call    dodecom            ; define our Take macro
  909.     jc    takope2            ; c = failure
  910.     inc    taklev            ; next Take
  911.     add    takadr,size takinfo    ; pointer to Take structure
  912.     mov    bx,takadr        ; pointer to Take structure
  913.     mov    ax,macptr        ; segment of buffer
  914.     mov    [bx].takbuf,ax        ; segment of Take buffer
  915.     mov    [bx].takcnt,tbufsiz-1    ; number of unread bytes
  916.     mov    [bx].takptr,1        ; init pointer to definition itself
  917.     clc                ; carry clear for success
  918. takope2:pop    dx
  919.     pop    cx
  920.     pop    bx
  921.     pop    ax
  922.     ret
  923. TAKOPEN    ENDP
  924.  
  925. ; Close Take file. Enter at Take level to be closed. Removes pseudo macro
  926. ; name <null>Tn and its buffer, closes disk file, pops Take level.
  927.  
  928. TAKCLOS    PROC    NEAR
  929.     cmp    taklev,0        ; anything to close?
  930.     jle    takclo2            ; le = no
  931.     push    ax
  932.     push    bx
  933.     push    cx
  934.     mov    temptc,3        ; length of name
  935.     mov    temptc+1,0
  936.     mov    temptc+2,'T'        ; name of <null>Tn
  937.     mov    al,taklev        ; Take level digit
  938.     add    al,'0'            ; add ascii bias
  939.     mov    temptc+3,al        ; last of the name
  940.     push    di
  941.     mov    di,offset temptc    ; pointer for remtab
  942.     call    remtab            ; remove possible old macro and buffer
  943.     pop    di
  944.     mov    bx,takadr        ; point to Take structure
  945.     cmp    [bx].taktyp,0feh    ; disk file?
  946.     jne    takclo1            ; ne = no, no buffer to deallocate
  947.     mov    bx,[bx].takhnd        ; get file handle
  948.     mov    ah,close2        ; close file
  949.     int    dos
  950.                     ; both disk and macro Takes
  951. takclo1:dec    taklev            ; pop Take level
  952.     sub    takadr,size takinfo    ; get previous Take's address
  953.     pop    cx
  954.     pop    bx
  955.     pop    ax
  956. takclo2:ret
  957. TAKCLOS    ENDP
  958.  
  959. ; add an entry to a keyword table
  960. ; enter with bx = table address, dx = ptr to new entry, macptr = string seg
  961. ; mccptr = offset of free bytes in table mcctab.
  962. ; no check is made to see if the entry fits in the table.
  963. addtab    proc    near
  964.     push    cx
  965.     push    si
  966.     push    es
  967.     push    bp
  968.     cld
  969.     mov    ax,ds
  970.     mov    es,ax        ; address data segment
  971.     mov    bp,bx        ; remember where macro name table starts
  972.     mov    cl,[bx]        ; pick up length of table
  973.     mov    ch,0
  974.     inc    bx        ; point to actual table
  975.     jcxz    addta4        ; cx = 0 if table is presently empty
  976.  
  977. addta1:    push    cx        ; preserve count
  978.     mov    si,dx        ; point to entry
  979.     lodsb            ; get length of new entry
  980.     mov    cl,[bx]        ; and length of table entry
  981.     mov    ah,0        ; assume they're the same size
  982.     cmp    al,cl        ; are they the same?
  983.     lahf            ; remember result of comparison
  984.     jae    addta2        ; is new smaller? ae = no, use table length
  985.     mov    cl,al        ; else use length of new entry
  986. addta2:    mov    ch,0
  987.     lea    di,[bx+1]    ; point to actual keyword
  988.     repe    cmpsb        ; compare strings
  989.     pop    cx        ; restore count
  990.     jb    addta4        ; below, insert before this one
  991.     jne    addta3        ; not below or same, keep going
  992.     sahf            ; same. get back result of length comparison
  993.     jb    addta4        ; if new len is smaller, insert here
  994.     jne    addta3        ; if not same size, keep going
  995.     mov    si,bx        ; else this is where entry goes
  996.     jmp    short addta6    ; no insertion required
  997. addta3:    mov    al,[bx]        ; length of keyword
  998.     mov    ah,0
  999.     add    bx,ax        ; skip this entry
  1000.     add    bx,4        ; len + $ + 16 bit value
  1001.     loop    addta1        ; and keep looking
  1002. addta4:    mov    si,bx        ; this is first location to move
  1003.     mov    di,bx
  1004.     inc    ds:byte ptr [bp] ; remember we're adding one
  1005.     jcxz    addta6        ; z = no more entries, forget this stuff
  1006.     mov    bh,0        ; this stays 0
  1007. addta5:    mov    bl,[di]        ; get length
  1008.     lea    di,[bx+di+4]    ; end is origin + length + 4 for len, $, value
  1009.     loop    addta5        ; loop thru remaining keywords
  1010.     mov    cx,di
  1011.     sub    cx,si        ; compute # of bytes to move
  1012.     push    si        ; preserve loc for new entry
  1013.     mov    si,di        ; first to move is last
  1014.     dec    si        ; minus one
  1015.     mov    di,dx        ; new entry
  1016.     mov    bl,[di]        ; get length
  1017.     lea    di,[bx+si+4]    ; dest is source + length of new + 4
  1018.     std            ; move backward
  1019.     rep    movsb        ; move the table down (compress it)
  1020.     cld            ; put flag back
  1021.     pop    si
  1022. addta6:    mov    di,si        ; this is where new entry goes
  1023.     mov    si,dx        ; this is where it comes from
  1024.     mov    cl,[si]        ; length
  1025.     mov    ch,0
  1026.     inc    cx        ; include count byte
  1027.     add    mccptr,cx    ; update free space pointer: cnt+name
  1028.     add    mccptr,3    ; plus '$' and pointer to string
  1029.     rep    movsb        ; insert new entry
  1030.     mov    al,'$'        ; add printing terminator
  1031.     stosb
  1032.     mov    ax,macptr    ; and string address
  1033.     stosw
  1034.     pop    bp
  1035.     pop    es
  1036.     pop    si
  1037.     pop    cx
  1038.     ret
  1039. addtab    endp
  1040.  
  1041. ; If new keyword matches an existing one then remove existing keyword,
  1042. ; its string definition, compress tables mcctab and macbuf, readjust string
  1043. ; pointers for each macro name, reduce number of macro table entries by one.
  1044. ; Enter with DI pointing at length byte of mac name (followed by mac name).
  1045. ; Otherwise, exit with no changes.  13 June 1987 [jrd]
  1046. remtab    proc    near
  1047.     push    ax
  1048.     push    bx
  1049.     push    cx
  1050.     push    si
  1051.     push    di
  1052.     mov    bx,offset mcctab+1    ; table of macro keywords
  1053.     mov    temp,0            ; temp = current keyword
  1054.     cmp    byte ptr mcctab,0    ; any macros defined?
  1055.     jne    remta1            ; ne = yes
  1056.     jmp    remtax            ; else exit now
  1057. remta1:                    ; match table keyword and text word
  1058.     mov    si,di            ; pointer to user's cnt+name
  1059.     mov    cl,[si]            ; length of user's macro name
  1060.     xor    ch,ch
  1061.     inc    si            ; point to new macro name
  1062.     cmp    cl,[bx]            ; compare length vs table keyword
  1063.     jne    remta4            ; ne = not equal lengths, try another
  1064.     push    si            ; lengths match, how about spelling?
  1065.     push    bx
  1066.     inc    bx            ; point at start of keyword
  1067. remta2:    mov    ah,[bx]            ; keyword char
  1068.     mov    al,[si]            ; new text char
  1069.     cmp    al,ah            ; test characters
  1070.     jne    remta3            ; ne = no match
  1071.     inc     si            ; move to next char
  1072.     inc    bx
  1073.     loop    remta2            ; loop through entire length
  1074. remta3:    pop    bx
  1075.     pop    si
  1076.     jcxz    remta6            ; z: cx = 0, exit with match;
  1077.                     ;  else select next keyword
  1078. remta4:    inc    temp            ; number of keyword to test next
  1079.     mov    cx,temp
  1080.     cmp    cl,mcctab        ; all done? Recall, temp starts at 0
  1081.     jb    remta5            ; b = not yet
  1082.     jmp    remtax            ; exhausted search, unsuccessfully
  1083. remta5:    mov    al,[bx]            ; cnt (keyword length from macro)
  1084.     xor    ah,ah
  1085.     add    ax,4            ; skip over '$' and two byte value
  1086.     add    bx,ax            ; bx = start of next keyword slot
  1087.     jmp    remta1            ; do another comparison
  1088.                     ; new name already present as a macro
  1089. remta6:    cld                ; clear macro string and macro name
  1090.     push    ds
  1091.     pop    es            ; set es to data segment
  1092.     mov    temp,bx            ; save ptr to found keyword
  1093.     mov    al,[bx]            ; cnt (keyword length of macro)
  1094.     xor    ah,ah
  1095.     add    ax,2            ; skip cnt and '$'
  1096.     add    bx,ax            ; point to string segment field
  1097.     add    ax,2            ; count segment field bytes
  1098.     sub    mccptr,ax        ; readjust free space ptr for names
  1099.     push    bx
  1100.     push    es
  1101.     mov    es,[bx]            ; segment of string
  1102.     mov    ah,freemem        ; free that memory block
  1103.     int    dos
  1104.     pop    es
  1105.     pop    bx
  1106.                     ; clear keyword table mcctab
  1107.     add    bx,2            ; compute source = next keyword
  1108.     mov    si,bx            ; address of next keyword
  1109.     mov    di,temp            ; address of found keyword
  1110.     mov    cx,offset mcctab+mcclen ; address of buffer end
  1111.     sub    cx,si            ; amount to move
  1112.     jcxz    remtax            ; cx = 0 means none
  1113.     rep    movsb            ; move down keywords (deletes current)
  1114.     dec    mcctab            ; one less keyword
  1115. remtax:    pop    di
  1116.     pop    si
  1117.     pop    cx
  1118.     pop    bx
  1119.     pop    ax
  1120.     ret
  1121. remtab    endp
  1122.  
  1123. ; Common Get keyword + Get Confirm sequence. Call with dx = keyword table,
  1124. ; bx = help message offset. Returns result in BX. Modifies AX, BX.
  1125. ; Returns carry clear if sucessful else carry set. Used in many places below.
  1126. keyend    proc    near
  1127.     mov    ah,cmkey
  1128.     call    comnd
  1129.     jnc    keyend1            ; nc = success
  1130.     ret                ; failure
  1131. keyend1:push    bx            ; save returned results around call
  1132.     mov    ah,cmeol        ; get c/r confirmation
  1133.     call    comnd
  1134.     pop    bx            ; recover keyword 16 bit value
  1135.     ret                ; return with carry from comnd
  1136. keyend    endp
  1137.  
  1138. srvdsa    proc    near            ; DISABLE Server commands
  1139.     mov    dx,offset srvdetab
  1140.     mov    bx,offset sdshlp
  1141.     call    keyend
  1142.     jc    srvdsa1            ; c = failure
  1143.     or    denyflg,bx        ; turn on bit (deny) for that item
  1144. srvdsa1:ret
  1145. srvdsa    endp
  1146.  
  1147. srvena    proc    near            ; ENABLE Server commands
  1148.     mov    dx,offset srvdetab    ; keyword table
  1149.     mov    bx,offset sdshlp    ; help on keywords
  1150.     call    keyend
  1151.     jc    srvena1            ; c = failure
  1152.     not    bx            ; invert bits
  1153.     and    denyflg,bx        ; turn off (enable) selected item
  1154. srvena1:ret
  1155. srvena    endp
  1156.  
  1157.  
  1158. ; This is the SET command
  1159. ; Called analyzers return carry clear for success, else carry set.
  1160. SETCOM    PROC    NEAR            ; Dispatch all SET commands from here
  1161.     mov    kstatus,0        ; global status, success
  1162.     mov    dx,offset settab    ; Parse a keyword from the set table
  1163.     mov    bx,offset sethlp
  1164.     mov    ah,cmkey
  1165.     call    comnd
  1166.     jc    setcom1            ; c = failure
  1167.     jmp    bx            ; execute analyzer routine
  1168. setcom1:ret
  1169. SETCOM    endp
  1170.  
  1171. SETATT    PROC    NEAR            ; Set attributes on | off
  1172.     mov    dx,offset atttab
  1173.     xor    bx,bx
  1174.     mov    ah,cmkey
  1175.     call    comnd
  1176.     jc    setatt3            ; c = failure
  1177.     mov    dx,bx            ; hold results in dx
  1178.     cmp    dl,0ffh            ; ON/OFF (all of them)?
  1179.     je    setatt1            ; e = yes
  1180.     push    dx
  1181.     mov    dx,offset ontab        ; get on/off state
  1182.     xor    bx,bx
  1183.     mov    ah,cmkey
  1184.     call    comnd
  1185.     pop    dx
  1186.     jc    setatt3            ; c = failure
  1187.     mov    dh,bl            ; store on/off state in dh
  1188. setatt1:push    dx
  1189.     mov    ah,cmeol
  1190.     call    comnd
  1191.     pop    dx
  1192.     jc    setatt3
  1193.     mov    al,flags.attflg        ; current flags
  1194.     not    dl            ; all but those affected
  1195.     and    al,dl            ; turn off affected flags
  1196.     or    dh,dh            ; off (dh = 0)?
  1197.     jz    setatt2            ; z = yes
  1198.     not    dl            ; affected flags back again as ones
  1199.     or    al,dl            ; turn on affected flags
  1200. setatt2:mov    flags.attflg,al
  1201. setatt3:ret
  1202. SETATT    ENDP
  1203.  
  1204. ; SET BAUD or SET SPEED
  1205. ; See system dependent routine BAUDST in file MSXxxx.ASM
  1206.  
  1207. ; SET BELL on or off
  1208.  
  1209. BELLST    PROC    NEAR
  1210.     mov    dx,offset ontab        ; on/off table
  1211.     xor    bx,bx            ; help
  1212.     call    keyend
  1213.     jc    bellst1            ; c = failure
  1214.     mov    flags.belflg,bl
  1215. bellst1:ret
  1216. BELLST    ENDP
  1217.  
  1218. ; SET BLOCK-CHECK
  1219.  
  1220. BLKSET    PROC    NEAR
  1221.     mov    dx,offset blktab    ; table
  1222.     xor    bx,bx            ; help, use table
  1223.     call    keyend
  1224.     jc    blkset1            ; c = failure
  1225.     mov    dtrans.chklen,bl    ; use this char as initial checksum
  1226. blkset1:ret
  1227. BLKSET    ENDP
  1228.  
  1229. ; SET COUNTER number    for script IF COUNTER number <command>
  1230. TAKECTR    PROC    NEAR
  1231.     mov    min,0            ; get decimal char code
  1232.     mov    max,65535        ; range is 0 to 65535 decimal
  1233.     mov    numhlp,offset takchlp    ; help message
  1234.     mov    numerr,0        ; error message
  1235.     call    num0            ; convert number, return it in ax
  1236.     jc    takect2            ; c = error
  1237.     push    ax            ; save numerical code
  1238.     mov    ah,cmeol
  1239.     call    comnd            ; get a confirm
  1240.     pop    ax            ; recover ax
  1241.     jc    takect2            ; c = failure
  1242.     cmp    taklev,0        ; in a Take file?
  1243.     je    takect4            ; e = no
  1244.     push    bx
  1245.     mov    bx,takadr
  1246.     mov    [bx].takctr,ax        ; set COUNT value
  1247.     pop    bx
  1248.     clc                ; success
  1249. takect2:ret
  1250. takect4:mov    dx,offset takcerr    ; say must be in Take file
  1251.     jmp    reterr            ; display msg and return carry clear
  1252. TAKECTR    ENDP
  1253.  
  1254. ; SET DEBUG {OFF | ON | SESSSION | PACKETS}
  1255.  
  1256. DEBST    PROC       NEAR
  1257.     mov    dx,offset debtab
  1258.     mov    bx,offset debhlp
  1259.     call    keyend
  1260.     jnc    debst1            ; nc = success
  1261.     ret                ; failure
  1262. debst1:    or    flags.debug,bl        ; set the mode, except for Off
  1263.     cmp    bx,0            ; OFF?
  1264.     jne    debst2            ; ne = no
  1265.     mov    flags.debug,0        ; set the DEBUG flags off
  1266. debst2:    clc                ; success
  1267.     ret
  1268. DEBST    ENDP
  1269.  
  1270. ; SET DESTINATION   of incoming files
  1271.  
  1272. DESSET    PROC    NEAR
  1273.     mov    dx,offset destab
  1274.     xor    bx,bx
  1275.     call    keyend
  1276.     jc    desset1            ; c = failure
  1277.     mov    flags.destflg,bl    ; set the destination flag
  1278. desset1:ret
  1279. DESSET    ENDP
  1280.  
  1281. ; SET DEFAULT-DISK    for sending/receiving, etc
  1282. ; See cwdir in file mssker
  1283.  
  1284. ; SET DELAY seconds   Used only for SEND command in local mode
  1285. SETDELY    PROC    NEAR
  1286.     mov    min,0            ; smallest acceptable value
  1287.     mov    max,63            ; largest acceptable value
  1288.     mov    numhlp,offset delyhlp    ; help message
  1289.     mov    numerr,0        ; complaint message
  1290.     call    num0            ; parse numerical input
  1291.     jc    setdly1            ; c = error
  1292.     mov    trans.sdelay,al
  1293. setdly1:ret                ; success or failure
  1294. SETDELY    ENDP
  1295.  
  1296. ; SET DISPLAY Quiet/Regular/Serial/7-Bit/8-Bit (inverse of Set Remote on/off)
  1297. ; Accepts two keywords in one command
  1298. disply    proc    near
  1299.     mov    ah,cmkey
  1300.     mov    dx,offset distab
  1301.     mov    bx,offset dishlp
  1302.     call    comnd
  1303.     jnc    displ0            ; nc = success
  1304.     ret                ; return failure
  1305. displ0:    mov    temp1,bx        ; save parsed value
  1306.     mov    temp2,0ffffh        ; assume no second keyword
  1307.     mov    comand.cmcr,1        ; bare CR's are allowed
  1308.     mov    ah,cmkey        ; parse for second keyword
  1309.     mov    dx,offset distab
  1310.     mov    bx,offset dishlp
  1311.     call    comnd
  1312.     jc    displ1            ; no keyword
  1313.     mov    temp2,bx        ; get key value
  1314. displ1:    mov    comand.cmcr,0        ; bare CR's are not allowed
  1315.     mov    ah,cmeol
  1316.     call    comnd            ; confirm
  1317.     jnc    displ2            ; nc = success
  1318.     ret                ; failure
  1319. displ2:    mov    ax,temp1        ; examine first key value
  1320.     call    dispcom            ; do common code
  1321.     mov    ax,temp2        ; examine second key value
  1322.     jmp    dispcom            ; finish in common code
  1323.  
  1324. dispcom:cmp    ax,0            ; check range
  1325.     jle    dispc3            ; le = not legal, ignore
  1326.     cmp    al,7            ; 7-8 bit value?
  1327.     jge    dispc2            ; ge = yes
  1328.     and    flags.remflg,not(dquiet+dregular+dserial)
  1329.     or    flags.remflg,al        ; set display mode
  1330.     clc                ; success
  1331.     ret                ; check next key value
  1332. dispc2:    cmp    al,8            ; set 8-bit wide display?
  1333.     ja    dispc3            ; a = bad value
  1334.     and    flags.remflg,not d8bit    ; assume want 7 bit mode
  1335.     cmp    al,7            ; really want 7 bit mode?
  1336.     je    dispc3            ; e = yes
  1337.     or    flags.remflg,d8bit    ; set 8 bit flag
  1338. dispc3:    clc                ; success
  1339.     ret                ; end of display common code
  1340. disply    endp
  1341.  
  1342.  
  1343. ; Set Dump filename  for saving screen images on disk.
  1344. ; Puts filename in global string dmpname
  1345. setdmp    proc    near
  1346.     mov    dx,offset rdbuf        ; work area
  1347.     mov    rdbuf,0            ; clear it
  1348.     mov     bx,offset dmphlp    ; help message
  1349.     mov    ah,cmword        ; allow paths
  1350.     call    comnd
  1351.     jc    setdmp2            ; c = failure
  1352.     mov    ah,cmeol
  1353.     call    comnd
  1354.     jc    setdmp2            ; c = failure
  1355.     mov    dx,offset rdbuf        ; assume we will use this text
  1356.     call    strlen            ; filename given?
  1357.     mov    si,dx            ; for strcpy
  1358.     cmp    cx,0            ; length of user's filename
  1359.     jg    setdmp1            ; g = filename is given
  1360.     mov    si,offset dmpdefnam    ; no name, use default instead
  1361. setdmp1:mov    di,offset dmpname    ; copy to globally available loc
  1362.     call    strcpy
  1363.     clc
  1364. setdmp2:ret
  1365. setdmp    endp
  1366.  
  1367. setdup    proc    near
  1368.     xor    bx,bx
  1369.     mov    dx,offset duptab
  1370.     call    keyend
  1371.     jc    setdup1            ; c = failure
  1372.     mov    si,portval
  1373.     mov    [si].duplex,bl        ; set value
  1374.     mov    ax,[si].flowc        ; get flow control characters
  1375.     mov    [si].floflg,al        ; flow control for full duplex
  1376.     mov    [si].ecoflg,0        ; turn off local echoing
  1377.     cmp    bl,0            ; full duplex?
  1378.     je    setdup1            ; e = yes
  1379.     mov    [si].floflg,0        ; no flow control for half duplex
  1380.     mov    [si].ecoflg,1        ; turn on local echoing
  1381. setdup1:ret
  1382. setdup    endp
  1383.  
  1384. ; SET EOF
  1385.  
  1386. SETEOF    PROC    NEAR
  1387.     xor    bx,bx
  1388.     mov    dx,offset seoftab
  1389.     call    keyend
  1390.     jc    seteof1            ; c = failure
  1391.     mov    flags.eofcz,bl        ; set value
  1392. seteof1:ret
  1393. SETEOF    ENDP
  1394.  
  1395. ; SET End-of-Packet char (for Sent packets)
  1396. ; Archic, here for downward compatibility
  1397. EOLSET    PROC    NEAR
  1398.     mov    stflg,'S'        ; set send/receive flag to Send
  1399.     jmp    sreol            ; use Set Send/Rec routine do the work
  1400. EOLSET    ENDP
  1401.  
  1402. ; SET ERRORLEVEL number
  1403. SETERL    PROC    NEAR
  1404.     mov    numhlp,offset erlhlp    ; help
  1405.     mov    numerr,0        ; error message
  1406.     mov    min,0            ; smallest number
  1407.     mov    max,255            ; largest magnitude
  1408.     call    num0            ; parse numerical input
  1409.     jc    seterl1            ; c = error
  1410.     mov    errlev,al        ; store result
  1411.     clc
  1412. seterl1:ret
  1413. SETERL    ENDP
  1414.  
  1415. ; SET ESCAPE character.
  1416. ; Accept literal control codes and \### numbers. [jrd] 18 Oct 1987
  1417. ESCSET    PROC    NEAR
  1418.     mov    ah,cmword
  1419.     mov    dx,offset rdbuf        ; work space
  1420.     mov    word ptr rdbuf,0    ; clear it
  1421.     mov    bx,offset eschlp    ; help
  1422.     call    comnd
  1423.     jc    escse2            ; c = failure
  1424.     cmp    ah,0            ; anything given?
  1425.     jne    escse1            ; ne = yes
  1426.     mov    dx,offset ermes6    ; more parameters needed
  1427.     jmp    reterr
  1428. escse1:    mov    ah,cmeol        ; get a confirm
  1429.     call    comnd
  1430.     jc    escse2            ; c = failure
  1431.     mov    si,offset rdbuf        ; source of chars
  1432.     call    katoi            ; convert escaped numbers to binary
  1433.     cmp    ax,spc            ; is it a control code?
  1434.     jae    escse3            ; ae = no, complain
  1435.     cmp    ax,0            ; non-zero too?
  1436.     je    escse3            ; e = zero
  1437.     mov    trans.escchr,al        ; save new escape char code
  1438.     clc
  1439. escse2:    ret
  1440. escse3:    mov    dx,offset escerr
  1441.     jmp    reterr
  1442. ESCSET    ENDP
  1443.  
  1444. ; SET FILE {WARNING, TYPE, CHARACTER-SET}
  1445. SETFILE    proc    near
  1446.     mov    dx,offset setfitab    ; SET FILE table
  1447.     xor    bx,bx
  1448.     mov    ah,cmkey
  1449.     call    comnd
  1450.     jc    setfix            ; c = failure
  1451.     or    bl,bl            ; Warning?
  1452.     jnz    setfi1            ; nz = no
  1453.                     ; entry point for old SET WARNING
  1454. FILWAR:    mov    dx,offset warntab    ; warning table, on, off, no-super
  1455.     xor    bx,bx
  1456.     call    keyend
  1457.     jc    setfix            ; c = failure
  1458.     mov    flags.flwflg,bl        ; set the filewarning flag
  1459.     ret
  1460.  
  1461. setfi1:    cmp    bl,1            ; SET FILE CHARACTER-SET?
  1462.     jne    setfi2            ; ne = no
  1463.     mov    dx,offset setchtab    ; table of char sets
  1464.     xor    bx,bx
  1465.     call    keyend            ; get the set id
  1466.     jc    setfix            ; c = error
  1467.     mov    flags.chrset,bx        ; save the id
  1468.     ret
  1469. setfi2:    cmp    bl,2            ; SET FILE TYPE?
  1470.     jne    setfix            ; ne = 3
  1471.     mov    dx,offset xftyptab    ; table of types
  1472.     xor    bx,bx
  1473.     call    keyend
  1474.     jc    setfix            ; c = error
  1475.     mov    dtrans.xtype,bl        ; store transfer type
  1476.     mov    trans.xtype,bl        ; store transfer type
  1477. setfix:    ret
  1478. SETFILE    endp
  1479.  
  1480. ; SET FLOW-CONTROL
  1481.  
  1482. FLOSET    PROC    NEAR
  1483.     mov    dx,offset flotab
  1484.       xor    bx,bx
  1485.     call    keyend
  1486.     jc    floset1            ; c = failure
  1487.     mov    si,portval
  1488.     mov    [si].flowc,bx        ; flow control values
  1489.     mov    [si].floflg,bl        ; say if doing flow control
  1490. floset1:ret
  1491. FLOSET    ENDP
  1492.  
  1493. ; SET HANDSHAKE
  1494. ; Add ability to accept general decimal code. [jrd]
  1495.  
  1496. HNDSET    PROC    NEAR
  1497.     mov    dx,offset hndtab    ; table to scan
  1498.     mov    bx,offset hnd1hlp    ; help message
  1499.     mov    ah,cmkey
  1500.     call    comnd
  1501.     jc    hnd2            ; c = failure
  1502.     cmp    bl,0ffh            ; want a general char code?
  1503.     jne    hnd1            ; ne = no
  1504.     mov    min,0            ; get decimal char code
  1505.     mov    max,31            ; range is 0 to 31 decimal
  1506.     mov    numhlp,offset ctlhlp    ; help message
  1507.     mov    numerr,0        ; error message
  1508.     call    num0            ; convert number, return it in ax
  1509.     jc    hnd2            ; c = error
  1510.     mov    bx,ax            ; recover numerical code
  1511. hnd1:    push    bx            ; handshake type
  1512.     mov    ah,cmeol
  1513.     call    comnd            ; get a confirm
  1514.     pop    bx            ; recover bx
  1515.     jc    hnd2            ; c = failure
  1516.     mov    si,portval
  1517.     cmp    bl,0            ; Setting handshake off?
  1518.     je    hnd0            ; Yes
  1519.     mov    [si].hndflg,1        ; And turn on handshaking
  1520.     mov    [si].hands,bl        ; Use this char as the handshake
  1521.     clc                ; success
  1522.     ret
  1523. hnd0:    mov    [si].hndflg,0        ; No handshaking
  1524.     clc                ; success
  1525. hnd2:    ret
  1526. HNDSET    ENDP
  1527.  
  1528. ;   SET INCOMPLETE file disposition
  1529.  
  1530. ABFSET    PROC    NEAR
  1531.     mov    dx,offset abftab
  1532.     xor    bx,bx
  1533.     call    keyend
  1534.     jc    abfset1            ; c = failure
  1535.     mov    flags.abfflg,bl        ; Set the aborted file flag
  1536. abfset1:ret
  1537. ABFSET    ENDP
  1538. ;
  1539. ; Set Input commands (default-timeout, timeout-action, case, echo)
  1540. ; By Jim Strudevant [jrs]
  1541. INPSET    PROC    NEAR
  1542.     mov    ah,cmkey        ; key word
  1543.     mov    dx,offset inptab    ; from inputtable
  1544.     xor    bx,bx            ; no hints
  1545.     call    comnd            ; get the word
  1546.     jc    inpset1            ; c = failure
  1547.     jmp    bx            ; do the sub command
  1548. inpset1:ret
  1549. ;
  1550. ; Set Input Default-timeout in seconds
  1551. ;
  1552. inptmo:    mov    numhlp,offset intoms    ; help
  1553.     mov    numerr,0        ; error message
  1554.     mov    min,0            ; smallest number
  1555.     mov    max,-1            ; largest magnitude
  1556.     call    num0            ; parse numerical input
  1557.     jc    inptmo1            ; c = error
  1558.     mov    script.indfto,ax    ; store result
  1559. inptmo1:ret
  1560. ;
  1561. ; Set Input Timeout action (proceed or quit)
  1562. ;
  1563. inpact:    mov    dx,offset inactb    ; from this list
  1564.     xor    bx,bx            ; no hints
  1565.     call    keyend            ; get it
  1566.     jc    inpact1            ; c = failure
  1567.     mov    script.inactv,bl    ; save the action
  1568. inpact1:ret
  1569. ;
  1570. ; Set Input Echo on or off
  1571. ;
  1572. inpeco:    mov    dx,offset ontab        ; from this list
  1573.     xor    bx,bx            ; no hints
  1574.     call    keyend            ; get it
  1575.     jc    inpeco1            ; c = failure
  1576.     mov    script.inecho,bl    ; save the action
  1577. inpeco1:ret
  1578. ;
  1579. ; Set Input Case observe or ignore
  1580. ;
  1581. inpcas:    mov    dx,offset incstb    ; from this list
  1582.     xor    bx,bx            ; no hints
  1583.     call    keyend            ; get it
  1584.     jc    inpcas1            ; c = failure
  1585.     mov    script.incasv,bl    ; save the action
  1586. inpcas1:ret
  1587. INPSET    ENDP
  1588.  
  1589. ; Set length of script buffer for INPUT/REINPUT at Kermit initialization
  1590. ; time via Environment. Called by command parser while doing Environment
  1591. ; reading in mssker.asm. Do not call after Kermit has initialized.
  1592. SETINPBUF proc    near
  1593.     mov    scpbuflen,128        ; store default buffer length
  1594.     mov    numhlp,0        ; no help
  1595.     mov    numerr,0        ; no error message
  1596.     mov    min,2            ; smallest number (must be non-zero)
  1597.     mov    max,64535        ; largest magnitude (16 bits worth)
  1598.     call    num0            ; parse numerical input
  1599.     jc    setinpbx        ; c = error
  1600.     mov    scpbuflen,ax        ; store result
  1601.     clc
  1602. setinpbx:ret
  1603. SETINPBUF endp
  1604.  
  1605. ; SET KEY
  1606. ; Jumps to new Set Key routine
  1607. setkey    proc    near        
  1608.     cmp    stkadr,0    ; keyboard translator present?
  1609.     je    setk4        ; e = no, use this routine
  1610.     mov    bx,stkadr    ; yes, get offset of procedure
  1611.     jmp    bx        ; jump to keyboard translator
  1612. setk4:    mov    dx,offset ermes5
  1613.     jmp    reterr        ; else print error message
  1614. setkey    endp
  1615.  
  1616. ; SET LOCAL-ECHO {ON | OFF}
  1617.  
  1618. LCAL    PROC    NEAR
  1619.     mov    dx,offset ontab
  1620.     xor    bx,bx
  1621.     call    keyend
  1622.     jc    lcal1            ; c = failure
  1623.     mov    si,portval
  1624.     mov    [si].ecoflg,bl        ; Set the local echo flag
  1625. lcal1:    ret
  1626. LCAL    ENDP
  1627.  
  1628. ; LOG  {PACKETS | SESSION | TRANSACTION} filename
  1629.  
  1630. setcpt    proc    near
  1631.     mov    dx,offset logtab    ; kinds of logging
  1632.     mov    bx,offset loghlp    ; help on kind of logging
  1633.     mov    ah,cmkey        ; parse keyword
  1634.     call    comnd
  1635.     jnc    setcp20            ; nc = success
  1636.     ret                ; failure
  1637. setcp20:mov    temp,bx            ; save the parsed value
  1638.     mov    dx,offset rdbuf        ; holds the complete filename
  1639.     mov    rdbuf,0            ; clear buffer
  1640.     mov     bx,offset filhlp    ; ask for filename
  1641.     mov    ah,cmword        ; allow paths
  1642.     call    comnd
  1643.     jnc    setcp21            ; nc = success
  1644.     ret                ; failure
  1645. setcp21:mov    ah,cmeol
  1646.     call    comnd            ; get a confirm
  1647.     jnc    setcp22            ; nc = success
  1648.     ret                ; failure
  1649. setcp22:mov    bx,temp            ; recover kind of logging
  1650.     mov    dx,offset rdbuf        ; length of filename to cx
  1651.     call    strlen            ; length of given filename
  1652.     test    bl,logpkt        ; packet logging?
  1653.     jz    setcp2            ; z = no, try others
  1654.     mov    dx,offset lpktnam    ; filename
  1655.     jcxz    setcp1            ; z = no filename given
  1656.     mov    si,offset rdbuf        ; get new name
  1657.     mov    di,dx            ; destination
  1658.     call    strcpy            ; replace old name
  1659. setcp1:    cmp    ploghnd,-1        ; packet log file already open?
  1660.     je    setcp6            ; e = no, open it
  1661.     jmp    setcp16            ; say file is open already
  1662.  
  1663. setcp2:    test    bl,logses        ; session logging?
  1664.     jz    setcp4            ; z = no, try others
  1665.     mov    dx,offset lsesnam    ; use default name
  1666.     jcxz    setcp3            ; z = no filename given
  1667.     mov    si,offset rdbuf        ; get new name
  1668.     mov    di,dx            ; destination
  1669.     call    strcpy            ; replace old name
  1670. setcp3:    cmp    sloghnd,-1        ; transaction file already open?
  1671.     je    setcp6            ; e = no, open it
  1672.     jmp    setcp16            ; say file is open already
  1673.  
  1674. setcp4:    test    bl,logtrn        ; transaction logging?
  1675.     jz    setcp14            ; z = no, error
  1676.     mov    dx,offset ltranam    ; use default name
  1677.     jcxz    setcp5            ; z = no filename given
  1678.     mov    si,offset rdbuf        ; get new name
  1679.     mov    di,dx            ; destination
  1680.     call    strcpy            ; replace old name
  1681. setcp5:    cmp    tloghnd,-1        ; transaction file already open?
  1682.     je    setcp6            ; e = no, open it
  1683.     jmp    setcp16            ; say file is open already
  1684.  
  1685. setcp6:    mov    ax,dx            ; place for filename for isfile
  1686.     call    isfile            ; does file exist already?
  1687.     jc    setcp7            ; c = does not exist so use create
  1688.     test    byte ptr filtst.dta+21,1fh ; file attributes, ok to write?
  1689.     jnz    setcp14            ; nz = no, use error exit    
  1690.     mov    ah,open2        ; open existing file
  1691.     mov    al,1+1            ;  for writing and reading
  1692.     int    dos
  1693.     jc    setcp14            ; if carry then error
  1694.     mov    bx,ax            ; file handle for seeking
  1695.     mov    cx,0            ; high order displacement
  1696.     mov    dx,0            ; low order part of displacement
  1697.     mov    ah,lseek        ; seek to EOF (to do appending)
  1698.     mov    al,2            ; says to EOF
  1699.     int    dos
  1700.     jmp    short setcp8
  1701.  
  1702. setcp7:    test    filtst.fstat,80h    ; access problem?
  1703.     jnz    setcp14            ; nz = yes, stop here
  1704.     mov    ah,creat2        ; function is create
  1705.     mov    cl,20H            ; turn on archive bit
  1706.     mov    ch,0
  1707.     int    dos            ; create the file, DOS 2.0
  1708.     jc    setcp14            ; if carry bit set then error
  1709.     mov    bx,ax            ; file handle
  1710.  
  1711. setcp8:    cmp    temp,logpkt        ; packet logging?
  1712.     jne    setcp9            ; ne = no
  1713.     mov    ploghnd,bx        ; save transaction log handle here
  1714.     jmp    short setcp12
  1715. setcp9:    cmp    temp,logses        ; session logging?
  1716.     jne    setcp10            ; ne = no
  1717.     mov    sloghnd,bx        ; save session log handle here
  1718.     jmp    short setcp12
  1719. setcp10:mov    tloghnd,bx        ; save transaction log handle here
  1720.  
  1721. setcp12:mov    ax,temp            ; kind of Logging
  1722.     or    flags.capflg,al        ; accumulate kinds of logging
  1723.     clc                ; success
  1724.     ret
  1725.  
  1726. setcp14:mov    dx,offset errcap    ; give error message
  1727.     jmp    reterr            ; and display it
  1728.  
  1729. setcp16:mov    ah,prstr        ; file already open
  1730.     mov    dx,offset erropn
  1731.     int    dos
  1732.     clc                ; return success
  1733.     ret
  1734. setcpt    endp
  1735.  
  1736. ; SET MODE LINE
  1737.  
  1738. MODL    PROC    NEAR
  1739.     mov    dx,offset ontab        ; parse an on or off
  1740.     xor    bx,bx            ; no special help
  1741.     call    keyend
  1742.     jc    modl1            ; c = failure
  1743.     mov    flags.modflg,bl        ; set flag appropriately
  1744. modl1:    ret
  1745. MODL    ENDP
  1746.  
  1747. ; SET PARITY
  1748.  
  1749. SETPAR    PROC    NEAR
  1750.     mov    dx,offset partab
  1751.     xor    bx,bx
  1752.     call    keyend
  1753.     jnc    setp1            ; nc = success
  1754.     ret
  1755. setp1:    mov    si,portval
  1756.     mov    [si].parflg,bl        ; Set the parity flag
  1757.     cmp    bl,parnon        ; Resetting parity to none?
  1758.     je    setp2            ; e = yes, reset 8 bit quote character
  1759.     mov    trans.ebquot,dqbin    ; we want quoting, active
  1760.     mov    dtrans.ebquot,dqbin    ; we want quoting, our default
  1761.     clc
  1762.     ret
  1763. setp2:    mov    trans.ebquot,'Y'    ; say will quote upon request
  1764.     mov    dtrans.ebquot,'Y'    ; and our default
  1765.     clc
  1766.     ret
  1767. SETPAR    ENDP
  1768.  
  1769. ; SET PROMPT  Allow user to change the "Kermit-MS>" prompt
  1770. ; {string} and \number notation permitted to represent special chars.
  1771. ; String will be made asciiz
  1772.  
  1773. PROMSET    PROC    NEAR
  1774.     mov    ah,cmline
  1775.     mov    bx,offset rdbuf        ; Read in the prompt
  1776.     mov    word ptr [bx],0        ; clear buffer
  1777.     mov    dx,offset prmmsg
  1778.     call    comnd
  1779.     jc    prom2            ; c = failure
  1780.     cmp    rdbuf,0            ; prompt string?
  1781.     jne    prom0            ; ne = yes
  1782.     mov    ax,offset kerm        ; no, restore default prompt
  1783.     jmp    prom1
  1784. prom0:    push    si            ; parse \### constants into
  1785.     push    di            ;  1 byte binary numbers inline
  1786.     mov    si,offset rdbuf        ; source = new prompt string
  1787.     mov    byte ptr [si-1+length rdbuf],0 ; plant null terminator
  1788.     mov    di,offset prm        ; destination
  1789.     call    cnvlin            ; convert \### in string to binary
  1790.     pop    di
  1791.     pop    si
  1792.     mov    bx,cx            ; get byte count
  1793.     mov    prm[bx],0        ; insert null terminator
  1794.     mov    ax,offset prm
  1795. prom1:    mov    prmptr,ax        ; remember it
  1796.     clc                ; success
  1797. prom2:    ret
  1798. PROMSET    ENDP
  1799.  
  1800. ; SET SERVER {LOGIN username password | TIMEOUT}
  1801.  
  1802. SETSRV    PROC    NEAR
  1803.     mov    dx,offset srvtab    ; set server table
  1804.     xor    bx,bx            ; use table for help
  1805.     mov    ah,cmkey        ; get keyword
  1806.     call    comnd
  1807.     jnc    setsrv1            ; c = success
  1808.     ret
  1809. setsrv1:cmp    bl,1            ; Login?
  1810.     jne    setsrv2            ; ne = no
  1811.     test    flags.remflg,dserver    ; acting as a server now?
  1812.     jz    setsrv3            ; z = no
  1813.     stc                ; fail
  1814.     ret
  1815. setsrv3:mov    dx,offset rdbuf        ; where to store local username
  1816.     mov    bx,offset luserh    ; help
  1817.     mov    comand.cmblen,16    ; buffer length
  1818.     mov    ah,cmword        ; get username
  1819.     call    comnd
  1820.     jc    setsrvx
  1821.     mov    bx,offset rdbuf+30    ; where to store local password
  1822.     mov    dx,offset lpassh    ; help
  1823.     mov    comand.cmblen,16    ; buffer length
  1824.     mov    ah,cmline        ; get password, allow spaces
  1825.     call    comnd
  1826.     jc    setsrvx
  1827.     mov    si,offset rdbuf        ; only now do we transfer to the
  1828.     mov    di,offset luser        ; active buffers
  1829.     call    strcpy
  1830.     mov    si,offset rdbuf+30
  1831.     mov    di,offset lpass
  1832.     call    strcpy
  1833.     clc
  1834.     ret
  1835.  
  1836. setsrv2:mov    min,0            ; Timeout, smallest acceptable value
  1837.     mov    max,255            ; largest acceptable value, one byte
  1838.     mov    numhlp,offset srvthlp    ; help message
  1839.     mov    numerr,0        ; complaint message
  1840.     call    num0            ; parse numerical input
  1841.     jc    setsrvx            ; c = error
  1842.     mov    srvtmo,al        ; store timeout value
  1843.     clc                ; success
  1844. setsrvx:ret
  1845.     
  1846. SETSRV    ENDP
  1847.  
  1848. ; SET RETRY value. Changes the packet retry limit.
  1849.  
  1850. RETRYSET PROC    NEAR
  1851.     mov    min,1            ; smallest acceptable value
  1852.     mov    max,63            ; largest acceptable value
  1853.     mov    numhlp,offset retryhlp    ; help message
  1854.     mov    numerr,0        ; complaint message
  1855.     call    num0            ; parse numerical input
  1856.     jc    retrys1            ; c = error
  1857.     mov    maxtry,al
  1858. retrys1:ret
  1859. RETRYSET ENDP
  1860.  
  1861. ; Set number of screens in terminal emulator rollback buffer at Kermit
  1862. ; initialization time via Environment. Called by command parser while doing
  1863. ; Environment reading in mssker.asm. Do not call after Kermit has initialized.
  1864. SETROLLB proc    near
  1865.     mov    npages,10        ; default number of rollback screens
  1866.     mov    numhlp,0        ; no help
  1867.     mov    numerr,0        ; no error message
  1868.     mov    min,0            ; smallest number
  1869.     mov    max,130            ; largest magnitude (16 bits worth)
  1870.     call    num0            ; parse numerical input
  1871.     jc    setrol1            ; c = error
  1872.     mov    npages,ax        ; store result
  1873.     clc
  1874. setrol1:ret
  1875. SETROLLB endp
  1876.  
  1877.  
  1878. ; SET TAKE-ECHO     on or off
  1879.  
  1880. TAKSET    PROC    NEAR
  1881.     mov    dx,offset ontab
  1882.     xor    bx,bx
  1883.     call    keyend
  1884.     jc    takset1            ; c = failure
  1885.     mov    flags.takflg,bl
  1886. takset1:ret
  1887. TAKSET    ENDP
  1888.  
  1889. ; SET TIMER     on or off during file transfer
  1890.  
  1891. TIMSET    PROC    NEAR
  1892.     mov    dx,offset ontab
  1893.     xor    bx,bx
  1894.     call    keyend
  1895.     jc    timset1            ; c = failure
  1896.     mov    flags.timflg,bl
  1897. timset1:ret
  1898. TIMSET    ENDP
  1899.  
  1900. ; SET WINDOW number of windows
  1901. WINSET    PROC    NEAR
  1902.     mov    min,1            ; smallest acceptable value
  1903.     mov    max,maxwind        ; largest acceptable value
  1904.     mov    numhlp,offset winhelp    ; help message
  1905.     mov    numerr,0        ; complaint message
  1906.     call    num0            ; parse numerical input
  1907.     jc    winse5            ; c = error
  1908.     mov    dtrans.windo,al        ; store default window size
  1909.     mov    trans.windo,al        ; and in active variable for makebuf
  1910.     call    makebuf            ; clear old buffers in prep for
  1911.     cbw
  1912.     mov    cx,ax
  1913.     mov    ax,maxpack        ; length of main DATA buffer
  1914.     xor    dx,dx            ;   extended numerator
  1915.     cmp    cx,1            ; zero means one here
  1916.     jbe    winse1
  1917.     div    cx            ; get new max packet length into ax
  1918. winse1:    cmp    trans.slong,ax        ; need to shorten sent packets?
  1919.     jbe    winse2            ; be = no
  1920.     mov    trans.slong,ax        ; set send value
  1921.     mov    cl,dtrans.spsiz        ; default regular packet send size
  1922.     mov    ch,0
  1923.     cmp    ax,cx            ; within normal packet range?
  1924.     ja    winse2            ; a = no
  1925.     mov    trans.spsiz,al        ; yes, update regular pkt size too
  1926. winse2:    cmp    trans.rlong,ax        ; need to shorten received pkts too?
  1927.     jbe    winse4            ; be = no
  1928.     mov    trans.rlong,ax        ; set receive value
  1929.     mov    cl,dtrans.rpsiz        ; default regular packet receive size
  1930.     mov    ch,0
  1931.     cmp    ax,cx            ; within normal packet range?
  1932.     ja    winse4            ; a = no
  1933.     mov    trans.rpsiz,al        ; yes, update regular pkt size too
  1934. winse4:    clc                ; success
  1935. winse5:    ret
  1936. WINSET    ENDP
  1937.  
  1938. ; SET SEND parameters
  1939.  
  1940. SENDSET    PROC    NEAR
  1941.     mov    stflg,'S'        ; Setting SEND parameter 
  1942.     mov    dx,offset stsrtb    ; Parse a keyword
  1943.     xor    bx,bx            ; no specific help
  1944.     mov    ah,cmkey
  1945.     call    comnd
  1946.     jc    sendset1        ; c = failure
  1947.     jmp    bx            ; do the action routine
  1948. sendset1:ret
  1949. SENDSET    ENDP
  1950.  
  1951. ; SET RECEIVE parameters
  1952.  
  1953. recset:    mov    stflg,'R'        ; Setting RECEIVE paramter
  1954.     mov    dx,offset stsrtb    ; Parse a keyword
  1955.     xor    bx,bx            ; no specific help
  1956.     mov    ah,cmkey
  1957.     call    comnd
  1958.     jc    recset1            ; c = failure
  1959.     jmp    bx            ; do the action routine
  1960. recset1:ret
  1961.  
  1962. remset    proc    near            ; Set REMOTE ON/OFF
  1963.     mov    dx,offset ontab
  1964.     mov    bx,offset remhlp
  1965.     call    keyend
  1966.     jc    remset2            ; c = failure
  1967.     and    flags.remflg,not (dquiet+dserial+dregular) ; no display bits
  1968.     or    bl,bl            ; want off state? (same as regular)
  1969.     jz    remset1            ; z = yes
  1970.     or    flags.remflg,dquiet    ; else on = quiet display
  1971.     clc
  1972.     ret
  1973. remset1:or    flags.remflg,dregular    ; off = regular display
  1974.     clc
  1975. remset2:ret
  1976. remset    endp
  1977.  
  1978.  
  1979. ; SET Send and Receive End-of-Packet char
  1980.  
  1981. sreol    PROC    NEAR
  1982.     mov    min,0            ; lowest acceptable value
  1983.     mov    max,1FH            ; largest acceptable value
  1984.     mov    numhlp,offset ctlhlp    ; reuse help message
  1985.     mov    numerr,0        ; error message address
  1986.     call    num0            ; get numerical input
  1987.     jc    sreol3            ; c = error
  1988.     cmp    stflg,'S'        ; setting SEND paramter?
  1989.     je    sreol1
  1990.     mov    trans.reol,al
  1991.     jmp    short sreol2
  1992. sreol1:    mov    dtrans.seol,al
  1993. sreol2:    mov    ah,dtrans.seol
  1994.     mov    trans.seol,ah
  1995.     clc
  1996. sreol3:    ret
  1997. sreol    ENDP
  1998.  
  1999.  
  2000. ; SET SEND and RECEIVE start-of-header
  2001.  
  2002. srsoh:    mov    min,0
  2003.     mov    max,1FH
  2004.     mov    numhlp,offset ctlhlp    ; Reuse help message
  2005.     mov    numerr,0        ; error message
  2006.     call    num0        ; Common routine for parsing numerical input
  2007.     jc    srsoh2            ; c = error
  2008.     cmp    stflg,'S'        ; Setting SEND paramter?
  2009.     je    srsoh1
  2010.     mov    trans.rsoh,al        ; set Receive soh
  2011.     clc                ; success
  2012.     ret
  2013. srsoh1:    mov    trans.ssoh,al        ; set Send soh
  2014.     clc                ; success
  2015.     ret
  2016. srsoh2:    ret
  2017.  
  2018. ; SET SEND and    RECEIVE TIMEOUT
  2019.  
  2020. srtim:    mov    min,0
  2021.     mov    max,94
  2022.     mov    numhlp,offset timhlp    ; Reuse help message
  2023.     mov    numerr,0        ; error message
  2024.     call    num0        ; Common routine for parsing numerical input
  2025.     jc    srtim3            ; c = error
  2026.     cmp    stflg,'S'        ; Setting SEND paramter?
  2027.     je    srtim1
  2028.     mov    trans.rtime,al
  2029.     jmp    short srtim2
  2030. srtim1:    mov    dtrans.stime,al
  2031. srtim2:    mov    ah,dtrans.stime
  2032.     mov    trans.stime,ah
  2033.     clc
  2034. srtim3:    ret
  2035.  
  2036. ; SET SEND and RECEIVE PACKET LENGTH
  2037. ; dtrans items are real, trans items are just for SHOW information
  2038.  
  2039. srpack:    mov    min,20
  2040.     mov    max,maxpack
  2041.     mov    numhlp,offset pakhlp    ; help
  2042.     mov    numerr,offset pakerr    ; error message
  2043.     call    num0
  2044.     jnc    srpaks0            ; nc = success
  2045.     ret                ; failure
  2046. srpaks0:cmp    stflg,'S'        ; setting send value?
  2047.     jne    srpakr            ; ne = receive
  2048.     mov    dtrans.slong,ax        ; set send max value
  2049.     mov    trans.slong,ax        ; store current active length
  2050.     mov    dtrans.spsiz,dspsiz    ; set regular 94 byte default
  2051.     cmp    ax,dspsiz        ; longer than regular packet?
  2052.     jae    srpaks1            ; ae = yes
  2053.     mov    dtrans.spsiz,al        ; shrink regular packet size too
  2054.     mov    trans.spsiz,al        ; shrink regular packet size too
  2055. srpaks1:mov    ax,maxpack        ; maximum buffer size
  2056.     xor    dx,dx
  2057.     mov    cl,dtrans.windo        ; current window slots
  2058.     xor    ch,ch
  2059.     div    cx            ; get active send packet length
  2060.     cmp    ax,dtrans.slong        ; longer than user specified?
  2061.     jae    srpaks4            ; ae = yes, employ user limit
  2062.     mov    cl,dtrans.spsiz        ; regular packet length
  2063.     mov    ch,0
  2064.     cmp    ax,cx            ; windowed shorter than normal packet?
  2065.     jae    srpaks3            ; ae = no
  2066.     mov    trans.spsiz,al        ; shrink regular pkt size
  2067.     mov    ah,0
  2068. srpaks3:mov    trans.slong,ax        ; store current active length
  2069. srpaks4:clc                ; success
  2070.     ret
  2071.  
  2072. srpakr:    mov    dtrans.rlong,ax        ; set receive max value
  2073.     mov    trans.rlong,ax        ; store active length
  2074.     mov    dtrans.rpsiz,drpsiz    ; set regular to default 94 bytes
  2075.     mov    trans.rpsiz,drpsiz
  2076.     cmp    ax,drpsiz        ; longer than a regular packet?
  2077.     jae    srpakr1            ; ae = yes
  2078.     mov    dtrans.rpsiz,al        ; shrink regular packet size too
  2079.     mov    trans.rpsiz,al
  2080. srpakr1:mov    ax,maxpack        ; maximum buffer size
  2081.     xor    dx,dx
  2082.     mov    cl,dtrans.windo        ; current window slots
  2083.     xor    ch,ch
  2084.     div    cx            ; get fully windowed packet length
  2085.     cmp    ax,dtrans.rlong        ; longer than user specified?
  2086.     jae    srpakr4            ; ae = yes, employ user limit
  2087.     mov    cl,dtrans.rpsiz        ; regular packet length
  2088.     mov    ch,0
  2089.     cmp    ax,cx            ; windowed shorter than normal packet?
  2090.     jae    srpakr3            ; ae = no
  2091.     mov    trans.rpsiz,al        ; shrink regular packet length
  2092.     mov    ah,0
  2093. srpakr3:mov    trans.rlong,ax        ; store active length
  2094. srpakr4:clc                ; success
  2095.     ret
  2096.  
  2097.  
  2098. ; SET SEND and RECEIVE number of padding characters
  2099.  
  2100. srnpd:    mov    min,0
  2101.     mov    max,94
  2102.     mov    numhlp,offset timhlp    ; reuse help message
  2103.     mov    numerr,0        ; error message
  2104.     call    num0            ; Parse numerical input
  2105.     jc    srnpd3            ; c = error
  2106.     cmp    stflg,'S'        ; Setting SEND paramter?
  2107.     je    srnpd1            ; e = yes
  2108.     mov    trans.rpad,al        ; set Receive padding
  2109.     jmp    short srnpd2
  2110. srnpd1:    mov    dtrans.spad,al        ; set default Send padding
  2111. srnpd2:    mov    al,dtrans.spad
  2112.     mov    trans.spad,al        ; update active array for I and S pkts
  2113.     clc
  2114. srnpd3:    ret
  2115.  
  2116. ; SET SEND and RECEIVE padding character
  2117.  
  2118. srpad:    mov    min,0
  2119.     mov    max,127
  2120.     mov    numhlp,offset padhlp
  2121.     mov    numerr,offset padhlp
  2122.     call    num0            ; parse numerical input
  2123.     jc    srpad4            ; c = error
  2124.     cmp    ah,127            ; this is allowed
  2125.     je    srpad1
  2126.     cmp    ah,32
  2127.     jb    srpad1            ; between 0 and 31 is OK too
  2128.     mov    ah,prstr
  2129.     mov    dx,offset padhlp
  2130.     int    dos
  2131. srpad1:    cmp    stflg,'S'        ; Send?
  2132.     je    srpad2            ; e = yes, else Receive
  2133.     mov    trans.rpadch,al        ; store receive pad char
  2134.     jmp    short srpad3
  2135. srpad2:    mov    dtrans.spadch,al    ; store Send pad char
  2136. srpad3:    mov    ah,dtrans.spadch
  2137.     mov    trans.spadch,ah      ; update active array for I and S pkts
  2138.     clc                ; success
  2139. srpad4:    ret
  2140.  
  2141. ; SET SEND and    RECEIVE control character prefix
  2142.  
  2143. srquo:    mov    min,33
  2144.     mov    max,126
  2145.     mov    numhlp,offset quohlp    ; help message
  2146.     mov    numerr,0        ; error message
  2147.     call    num0            ; Parse numerical input
  2148.     jc    srquo3            ; c = error
  2149.     cmp    stflg,'S'        ; Setting outgoing quote char?
  2150.     je    srquo1            ; e = yes
  2151.     mov    trans.rquote,al        ; set Receive quote char
  2152.     jmp    short srquo2
  2153. srquo1:    mov    dtrans.squote,al    ; set Send quote char
  2154. srquo2:    clc
  2155. srquo3:    ret
  2156.  
  2157. ; SET SEND Pause number    of milliseconds
  2158.  
  2159. srpaus:    mov    min,0
  2160.     mov    max,127
  2161.     mov    numhlp,offset pauhlp    ; help
  2162.     mov    numerr,0
  2163.     call    num0            ; Parse numerical input
  2164.     pushf                ; save carry for error state
  2165.     cmp    stflg,'S'        ; Setting SEND paramter?
  2166.     je    srpau0
  2167.     popf
  2168.     mov    dx,offset ermes5    ; "Not implemented" msg
  2169.     jmp    reterr            ; print error message
  2170. srpau0:    popf
  2171.     jc    srpau1            ; c = error
  2172.     mov    spause,al        ; store value
  2173. srpau1:    ret
  2174.  
  2175. ; SET TRANSFER  CHARACTER-SET {Latin1, Transparent}
  2176. sxfer    proc    near
  2177.     mov    dx,offset xfertab    ; table of TRANSFER keywords
  2178.     xor    bx,bx
  2179.     mov    ah,cmkey        ; get next keyword
  2180.     call    comnd
  2181.     jc    sxfer1            ; c = error
  2182.     or    bl,bl            ; Character-set?
  2183.     jnz    sxfer1            ; nz = no
  2184.     mov    dx,offset xfchtab    ; Character-set table
  2185.     mov    bx,offset xfchhlp    ; help text
  2186.     call    keyend
  2187.     jc    sxfer1            ; c = error
  2188.     mov    dtrans.xchset,bl    ; store transfer char set ident
  2189.     mov    trans.xchset,bl        ; store transfer char set ident
  2190.     clc
  2191.     ret
  2192. sxfer1:    stc
  2193.     ret
  2194. sxfer    endp
  2195.  
  2196. ; SET TRANSLATION           Connect mode translate characters
  2197. ; SET TRANSLATION INPUT {Original-byte New-byte | ON | OFF}
  2198. ; SET TRANSLATION KEYBOARD {ON | OFF}, default is ON
  2199.  
  2200. SETRX    PROC    NEAR            ; translate incoming serial port char
  2201.     mov    ah,cmkey
  2202.     mov    dx,offset trnstab    ; direction table (just one entry)
  2203.     xor    bx,bx            ; no help
  2204.     call    comnd
  2205.     jnc    setrx0            ; nc = success
  2206.     ret                ; failure
  2207. setrx0:    cmp    bx,2            ; Keyboard?
  2208.     jne    setrx0b            ; ne = no
  2209.     jmp    setr11            ; do keyboard
  2210. setrx0b:mov    dx,offset rdbuf        ; our work space
  2211.     mov    word ptr rdbuf,0    ; insert terminator
  2212.     mov    bx,offset srxhlp1    ; first help message
  2213.     mov    ah,cmword        ; parse a word
  2214.     call    comnd            ; get incoming byte pattern
  2215.     jnc    setrx0a            ; nc = success
  2216.     ret
  2217. setrx0a:or    ah,ah            ; any text given?
  2218.     jz    setr6            ; nz = no
  2219.     mov    temp,ax            ; save byte count here
  2220.     mov    ax,word ptr rdbuf    ; get first two characters
  2221.     or    ax,2020h        ; convert upper to lower case
  2222.     cmp    ax,'fo'            ; first part of word OFF?
  2223.     je    setr6            ; e = yes, go analyze
  2224.     cmp    ax,'no'            ; word ON?
  2225.     je    setr6            ; e = yes, go do it
  2226.     mov    si,offset rdbuf        ; convert text to number
  2227.     call    katoi            ; number converter procedure, to ax
  2228.     jnc    setr1            ; nc = success    
  2229.     cmp    byte ptr temp+1,1    ; just one character given?
  2230.     jne    setr6            ; ne = no, so bad code
  2231. setr1:    mov    min,ax            ; save byte code here
  2232.     mov    dx,offset rdbuf        ; our work space
  2233.     mov    word ptr rdbuf,0    ; insert terminator
  2234.     mov    bx,offset srxhlp1    ; first help message
  2235.     mov    ah,cmword        ; parse a word
  2236.     call    comnd            ; get incoming byte pattern
  2237.     jnc    setr2            ; nc = success
  2238.     ret                ; failure
  2239. setr2:    or    ah,ah            ; any text given?
  2240.     jz    setr6            ; z = no
  2241.     mov    temp,ax            ; save byte count here
  2242.     mov    si,offset rdbuf        ; convert text to number
  2243.     call    katoi            ; number converter procedure
  2244.     jnc    setr3            ; nc = success
  2245.     cmp    byte ptr temp+1,1    ; just one character given?
  2246.     jne    setr6            ; ne = no, so bad code or ON/OFF
  2247. setr3:    mov    max,ax            ; save byte code here
  2248.     mov    ah,cmeol        ; get a confirm
  2249.     call    comnd
  2250.     jnc    setr3a            ; nc = success
  2251.     ret                ; failure
  2252. setr3a:    mov    bx,min            ; bl = incoming byte code
  2253.     xor    bh,bh
  2254.     mov    ax,max            ; al = local (translated) byte code
  2255.     mov    rxtable [bx],al        ; store in rx translate table
  2256.     clc                ; success
  2257.     ret
  2258.  
  2259. setr6:    mov    ah,cmeol        ; get a confirm
  2260.     call    comnd
  2261.     jnc    setr6a            ; nc = success
  2262.     ret                ; failure
  2263. setr6a:    mov    dx,offset badrx        ; assume bad construction
  2264.     or    word ptr rdbuf,2020h    ; convert to lower case
  2265.     or    rdbuf+2,20h        ; first three chars
  2266.     cmp    word ptr rdbuf,'fo'    ; key word OFF?
  2267.     jne    setr8            ; ne = no
  2268.     cmp    rdbuf+2,'f'        ; last letter of OFF?
  2269.     jne    setr8            ; ne = no
  2270.     mov    rxtable+256,0        ; OFF is status byte = zero
  2271.     mov    dx,offset rxoffmsg    ; say translation is turned off
  2272.     jmp    setr9
  2273. setr8:    cmp    word ptr rdbuf,'no'    ; keyword ON?
  2274.     jne    setr9a            ; ne = no, error
  2275.     mov    rxtable+256,1        ; ON is status byte non-zero
  2276.     mov    dx,offset rxonmsg    ; say translation is turned on
  2277. setr9:    cmp    taklev,0        ; executing from a Take file?
  2278.     je    setr9a            ; e = no
  2279.     cmp    flags.takflg,0        ; echo contents of Take file?
  2280.     je    setr10            ; e = no
  2281. setr9a:    mov    ah,prstr        ; bad number message
  2282.     int    dos
  2283. setr10:    clc
  2284.     ret
  2285. setr11:    mov    ah,cmkey        ; SET TRANSLATION KEYBOARD
  2286.     mov    dx,offset ontab        ; on/off
  2287.     xor    bx,bx
  2288.     call    comnd
  2289.     jnc    setr12            ; nc = success
  2290.     ret
  2291. setr12:    mov    ah,cmeol        ; get a confirm
  2292.     call    comnd
  2293.     jnc    setr13            ; nc = success
  2294.     ret                ; failure
  2295. setr13:    mov    flags.xltkbd,bl        ; set keyboard translation on/off
  2296.     clc
  2297.     ret
  2298. SETRX    ENDP
  2299.  
  2300. ; SET TRANSMIT {FILL, LF, Prompt} {ON, OFF, or value}
  2301. SETXMIT    proc    near
  2302.     mov    dx,offset xmitab    ; TRANSMIT keyword table
  2303.     xor    bx,bx
  2304.     mov    ah,cmkey        ; get keyword
  2305.     call    comnd
  2306.     jnc    setxmi1            ; nc = success
  2307.     ret
  2308. setxmi1:cmp    bl,2            ; SET TRANSMIT PROMPT?
  2309.     jne    setxmi2            ; ne = no
  2310.     mov    ah,cmword
  2311.     mov    dx,offset rdbuf+1    ; put answer here
  2312.     mov    bx,offset xpmthlp
  2313.     call    comnd
  2314.     jc    setxmi1d        ; c = error
  2315.     push    ax            ; save length in ah
  2316.     mov    ah,cmeol        ; get a confirm
  2317.     call    comnd
  2318.     pop    ax
  2319.     jc    setxmi1d        ; c = failure
  2320.     mov    al,rdbuf+1
  2321.     cmp    ah,1            ; a single char?
  2322.     je    setxmi1c        ; e = yes, use it as the prompt char
  2323.     mov    si,offset rdbuf+1
  2324.     cmp    byte ptr [si],'\'    ; already quoted?
  2325.     je    setxmi1b        ; e = yes
  2326.     mov    rdbuf,'\'        ; add a numerical quote
  2327.     dec    si            ; point to our escape char
  2328. setxmi1b:call    katoi            ; convert number in rdbuf
  2329.     jc    setxmi1d        ; c = no number, error
  2330. setxmi1c:mov    script.xmitpmt,al    ; store new prompt value
  2331. setxmi1d:ret
  2332.  
  2333. setxmi2:cmp    bl,1            ; LF?
  2334.     jne    setxmi3            ; ne = no
  2335.     mov    dx,offset ontab        ; on or off table
  2336.     xor    bx,bx
  2337.     call    keyend
  2338.     jc    setxmix            ; c = failure
  2339.     mov    script.xmitlf,bl    ; set the xmitlf flag
  2340.     ret
  2341.  
  2342. setxmi3:mov    ah,cmword        ; FILL, get a word sized token
  2343.     mov    dx,offset rdbuf+1    ; put it here
  2344.     mov    bx,offset xfilhlp    ; help
  2345.     call    comnd
  2346.     jc    setxmix            ; c = failure
  2347.     push    ax            ; save length in ah
  2348.     mov    ah,cmeol        ; get a confirm
  2349.     call    comnd
  2350.     pop    ax
  2351.     jc    setxmix            ; c = failure
  2352.     mov    cl,ah            ; word length
  2353.     xor    ch,ch
  2354.     cmp    cl,1            ; just one character?
  2355.     ja    setxmi4            ; a = no, there's more
  2356.     mov    al,rdbuf+1        ; get the char
  2357.     mov    script.xmitfill,al    ; store Fill char
  2358.     ret
  2359. setxmi4:mov    ax,word ptr rdbuf+1
  2360.     or    ax,2020h        ; to lower
  2361.     cmp    ax,'on'            ; "none"?
  2362.     jne    setxmi5            ; ne = no
  2363.     mov    script.xmitfill,0    ; no Filling
  2364.     ret
  2365. setxmi5:cmp    ax,'ps'            ; "space"?
  2366.     jne    setxmi6            ; ne = no
  2367.     mov    script.xmitfill,' '    ; use space as filler
  2368.     ret
  2369. setxmi6:mov    si,offset rdbuf+1
  2370.     cmp    byte ptr [si],'\'    ; already quoted?
  2371.     je    setxmi7            ; e = yes
  2372.     mov    rdbuf,'\'        ; add a numerical quote
  2373.     dec    si            ; point to our escape char
  2374. setxmi7:call    katoi            ; convert number in rdbuf
  2375.     jc    setxmix            ; c = no number, error
  2376.     mov    script.xmitfill,al    ; set the xmitfill flag
  2377. setxmix:ret
  2378. SETXMIT    endp
  2379.  
  2380. ; SET UNKNOWN-CHARACTER-SET {DISCARD, KEEP}, default is KEEP
  2381. unkchset proc    near
  2382.     mov    dx,offset unkctab    ; keep/reject keyword table
  2383.     mov    bx,offset unkchhlp
  2384.     call    keyend
  2385.     jc    unkchx            ; c = failure
  2386.     mov    flags.unkchs,bl        ; 0 = keep, else reject
  2387. unkchx:    ret
  2388. unkchset endp
  2389.  
  2390. ; Common routine for parsing numerical input
  2391. ; Enter with numhlp = offset of help message, numerr = offset of optional
  2392. ;  error message, min, max = allowable range of values.
  2393. ; Returns value in ax, or does parse error return.
  2394. ; Changes ax,bx,dx,si.            [jrd] 18 Oct 1987
  2395. num0:    mov    dx,offset rdbuf+1    ; were to put text
  2396.     mov    word ptr rdbuf,0    ; clear the buffer
  2397.     mov    bx,numhlp        ; help text
  2398.     mov    ah,cmword        ; get a word
  2399.     call    comnd
  2400.     jc    num0x            ; c = failure
  2401.     mov    ah,cmeol
  2402.     call    comnd            ; Get a confirm
  2403.     jc    num0x            ; c = failure
  2404.     mov    si,offset rdbuf+1
  2405.     cmp    rdbuf+1,'\'        ; already quoted?
  2406.     je    num0a            ; e = yes
  2407.     mov    rdbuf,'\'        ; add a numerical quote
  2408.     dec    si            ; point to our escape char
  2409. num0a:    call    katoi            ; convert number in rdbuf
  2410.     jc    num0er            ; c = no number, error
  2411.     cmp    ax,max            ; largest permitted value
  2412.     ja    num0er            ; a = error
  2413.     cmp    ax,min            ; smallest permitted value
  2414.     jb    num0er            ; b = error
  2415.     clc
  2416. num0x:    ret                ; return value in ax
  2417.  
  2418. num0er:    mov    ah,prstr
  2419.     mov    dx,numerr        ; comand-specific error message, if any
  2420.     cmp    dx,0            ; was any given?
  2421.     je    num0e1            ; e = no, use generic msg
  2422.     int    dos            ; show given error message
  2423.     jmp    short num0e2
  2424. num0e1:    mov    dx,offset nummsg1    ; get address of numeric error message
  2425.     int    dos
  2426.     mov    ax,min            ; smallest permitted number
  2427.     call    decout            ; display decimal number in ax
  2428.     mov    ah,prstr
  2429.     mov    dx,offset nummsg2    ; "and"
  2430.     int    dos
  2431.     mov    ax,max            ; largest permitted number
  2432.     call    decout
  2433. num0e2:    stc
  2434.     ret
  2435.  
  2436. ; routine to print an error message, then exit without error status
  2437. ; expects message in dx
  2438. reterr    proc    near
  2439.     mov    ah,prstr
  2440.     int    dos
  2441.     clc
  2442.     ret
  2443. reterr    endp
  2444.  
  2445. code    ends
  2446.     end
  2447.