home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / msk316src.zip / MSSSET.ASM < prev    next >
Assembly Source File  |  1999-10-14  |  143KB  |  4,840 lines

  1.     NAME    mssset
  2. ; File MSSSET.ASM
  3.     include mssdef.h
  4. ;    Copyright (C) 1982, 1999, Trustees of Columbia University in the 
  5. ;    City of New York.  The MS-DOS Kermit software may not be, in whole 
  6. ;    or in part, licensed or sold for profit as a software product itself,
  7. ;    nor may it be included in or distributed with commercial products
  8. ;    or otherwise distributed by commercial concerns to their clients 
  9. ;    or customers without written permission of the Office of Kermit 
  10. ;    Development and Distribution, Columbia University.  This copyright 
  11. ;    notice must not be removed, altered, or obscured.
  12. ;
  13. ; Edit history
  14. ; 12 Jan 1995 version 3.14
  15. ; Last edit
  16. ; 12 Jan 1995
  17.  
  18.     public    setcom, prmptr, dodef, setcpt, docom, stkadr, rdbuf, reset
  19.     public    setrx, rxtable, srvdsa, srvena, mcctab, takclos, ask
  20.     public    askq, assign, initibm, mccptr, setinpbuf, setrollb, npages
  21.     public    xfchtab, xftyptab, com1port, com2port, com3port, com4port
  22.     public    flotab, popcmd, domacptr, warntab, portirq, portfifo, dodecom
  23.     public    xfertab1, xfertab2, xfertab3, rollwidth, setwidth, abftab
  24.     public    localmac, getok, takeerror, macroerror, getc, dial, docnv
  25.     public    takopen_sub, takopen_file, takopen_macro, _forinc, poplevel
  26.     public    hide_assign, hide_define, declare, marray, forcmd, undefine
  27. ifndef    no_tcp
  28.     public    tcpaddress,tcpsubnet,tcpdomain,tcpgateway,tcpprimens
  29.     public    tcpsecondns,tcphost,tcpbcast,tcpport,tcppdint,tcpttbuf
  30.     public    tcpbtpserver,tcpnewline,tcpdebug,tcpmode,tcpmss
  31. endif    ; no_tcp
  32.  
  33. braceop    equ    7bh        ; opening curly brace
  34. bracecl    equ    7dh        ; closing curly brace
  35.  
  36. maketab    MACRO            ; Assembler Macro to make rxtable [jrd]
  37. cnt = 0
  38.     rept 256
  39.     db    cnt        ; initialize table to 0 .. 255
  40. cnt = cnt + 1
  41.     endm
  42.     db    0        ; table off (0) or on (1) indicator
  43. ENDM
  44.  
  45. data     segment
  46.     extrn    comand:byte, flags:byte, trans:byte, takadr:word, taklev:byte
  47.     extrn    portval:word, dtrans:byte, spause:word, machnam:byte
  48.     extrn    filtst:byte, maxtry:byte, script:byte, denyflg:word
  49.     extrn    sloghnd:word, ploghnd:word, tloghnd:word, cardet:byte
  50.     extrn    decbuf:byte, kstatus:word, errlev:byte, srvtmo:byte
  51.     extrn    luser:byte, lpass:byte, destab:byte, blktab:byte
  52.     extrn    seoftab:byte, dmpname:byte, lsesnam:byte, lpktnam:byte
  53.     extrn    ltranam:byte, incstb:byte, inactb:byte, rxoffmsg:byte
  54.     extrn    rxonmsg:byte, scpbuflen:word, setchtab:byte
  55.     extrn    prnname:byte, prnhand:word, outpace:word, apctrap:byte
  56.     extrn    protlist:byte, rcvpathflg:byte, sndpathflg:byte
  57.     extrn    fossilflag:byte, ifelse:byte, oldifelse:byte
  58.     extrn    domath_ptr:word, domath_cnt:word, domath_msg:word
  59.     extrn    streaming:byte
  60.  
  61. rxtable    equ THIS BYTE        ; build 256 byte Translation Input table
  62.     maketab            ; table rxtable is used by Connect mode
  63.  
  64. kerm    db    'MS-Kermit>',0        ; default ASCIIZ prompt
  65. promptbuf db    80 dup (0),0        ; buffer for new ASCIIZ prompt
  66. rdbuf    db    cmdblen dup (?)        ; work space; room for macro def
  67.                     ;  and for Status display line
  68. settemp db    100 dup (0)    ; temp for hidemac/unhide
  69. stflg    db    0        ; Says if setting SEND or RECEIVE parameter
  70. defkind    db    0        ; 0 for ASSIGN, 1 for DEFINE
  71. ermes1    db    cr,lf,'?Too many macro names$'
  72. ermes2    db    cr,lf,bell,'?No room for Take file buffer or Macro definition'
  73.     db    cr,lf,bell,'$'
  74. ermes4    db    cr,lf,'?Too many active Take files and Macros',cr,lf, bell,'$'
  75. ermes5    db    cr,lf,'?Not implemented$'
  76. ermes6    db    cr,lf,'?More parameters are needed$'
  77. ermes7    db    cr,lf,'?Cannot use RTS/CTS on non-UART ports$'
  78. ermes8    db    cr,lf,'?Cannot use HARDWARE parity on non-UART ports$'
  79. errcap    db    cr,lf,'?Unable to open that file$'
  80. erropn    db    cr,lf,'?Log file is already open$'
  81. badrx    db    cr,lf,'?Expected ON, OFF, or \nnn$'
  82. escerr    db    cr,lf,'?Not a control code$'
  83. takcerr    db    cr,lf,'?Note: command is valid only in Take files and Macros$'
  84. dmpdefnam db    'Kermit.scn',0        ; asciiz default screen dump filename
  85. prndefnam db    'PRN',0            ; asciiz default printer name
  86. xfchbad    db    cr,lf,'Warning: forcing FILE CHARACTER-SET to CP866$'
  87. xfchbad2 db    cr,lf,'Warning: forcing FILE CHARACTER-SET to Shift-JIS$'
  88. xfchbad3 db    cr,lf,'Warning: forcing FILE CHARACTER-SET to CP862$'
  89. setchmsg db    cr,lf,'Warning: forcing TRANSFER CHARACTER-SET to CYRILLIC$'
  90. setchmsg2 db    cr,lf,'Warning: forcing TRANSFER CHARACTER-SET to'
  91.     db    ' Japanese-EUC$'
  92. setchmsg3 db  cr,lf,'Warning: forcing TRANSFER CHARACTER-SET to HEBREW-ISO$'
  93. badcntlmsg db    cr,lf,'?Number is not in range of 0..31, 128..159$'
  94. getdef    db    'Please respond Yes or No ',0    ; ASCII, used as prompt
  95. crlf    db    cr,lf,'$'
  96. space    db    ' ',0
  97.  
  98. srvtab    db    2            ; SET SERVER table
  99.     mkeyw    'Login',1
  100.     mkeyw    'Timeout',2
  101.  
  102. ifndef    no_network
  103. settab     db    64                    ; Set table
  104. else
  105. settab     db    64 - 3                    ; Set table
  106. endif    ; no_network
  107.     mkeyw    'Alarm',setalrm
  108.     mkeyw    'Attributes',setatt
  109.     mkeyw    'Baud',baudst
  110.     mkeyw    'Bell',bellst
  111.     mkeyw    'Block-check-type',blkset
  112.     mkeyw    'Carrier',setcar
  113.     mkeyw    'COM1',com1port
  114.     mkeyw    'COM2',com2port
  115.     mkeyw    'COM3',com3port
  116.     mkeyw    'COM4',com4port
  117.     mkeyw    'Control-character',cntlset
  118.     mkeyw    'Count',takectr
  119.     mkeyw    'Debug',debst
  120.     mkeyw    'Default-disk',cwdir
  121.     mkeyw    'Delay',setdely
  122.     mkeyw    'Destination',desset
  123.     mkeyw    'Display',disply
  124.     mkeyw    'Dump',setdmp
  125.     mkeyw    'Duplex',setdup
  126.     mkeyw    'End-of-Line',eolset
  127.     mkeyw    'EOF',seteof
  128.     mkeyw    'Errorlevel',seterl
  129.     mkeyw    'Escape-character',escset
  130.     mkeyw    'Exit',setexitwarn
  131.     mkeyw    'File',setfile
  132.     mkeyw    'Flow-control',floset
  133.     mkeyw    'Fossil',fosset
  134.     mkeyw    'Handshake',hndset
  135.     mkeyw    'Incomplete',abfset
  136.     mkeyw    'Input',inpset
  137.     mkeyw    'Key',setkey
  138.     mkeyw    'Line',coms
  139.     mkeyw    'Local-echo',lcal
  140.     mkeyw    'Macro',setmacerr
  141.     mkeyw    'Mode-line',modl
  142.     mkeyw    'Modem',setmodem
  143. ifndef    no_network
  144.     mkeyw    'NetBios-name',setnbios
  145. endif    ; no_network
  146.     mkeyw    'Output',setoutput
  147.     mkeyw    'Parity',setpar
  148.     mkeyw    'Port',coms
  149.     mkeyw    'Printer',setprn
  150.     mkeyw    'Prompt',promset
  151.     mkeyw    'Receive',recset
  152.     mkeyw    'Remote',remset
  153.     mkeyw    'Repeat',repset
  154.     mkeyw    'Retry',retryset
  155.     mkeyw    'Rollback',setrollb
  156.     mkeyw    'Send',sendset
  157.     mkeyw    'Server',setsrv
  158.     mkeyw    'Speed',baudst
  159.     mkeyw    'Stop-bits',stopbit
  160.     mkeyw    'Streaming',strmmode
  161.     mkeyw    'Take',takset
  162. ifndef    no_tcp
  163.     mkeyw    'TCP/IP',tcpipset
  164.     mkeyw    'Telnet',tcpipset
  165. endif    ; no_tcp
  166.     mkeyw    'Terminal',vts
  167.     mkeyw    'Timer',timset
  168.     mkeyw    'Transfer',sxfer
  169.     mkeyw    'xfer',sxfer        ; hidden synonym
  170.     mkeyw    'Translation',setrx
  171.     mkeyw    'Transmit',setxmit
  172.     mkeyw    'Unknown-character-set',unkchset
  173.     mkeyw    'Warning',filwar
  174.     mkeyw    'Windows',winset
  175.  
  176. setfitab db    6            ; Set File command table
  177.     mkeyw    'Character-Set',1
  178.     mkeyw    'Collision',0
  179.     mkeyw    'Display',3
  180.     mkeyw    'Incomplete',4
  181.     mkeyw    'Type',2
  182.     mkeyw    'Warning',0
  183.  
  184. setrep    db    2            ; SET REPEAT
  185.     mkeyw    'Counts',0
  186.     mkeyw    'Prefix',1
  187.  
  188. xfertab    db    5            ; SET TRANSFER table
  189.     mkeyw    'Character-set',0
  190.     mkeyw    'CRC',4
  191.     mkeyw    'Locking-shift',1
  192.     mkeyw    'Mode',3
  193.     mkeyw    'Translation',2
  194.  
  195. xfertab1 db    3            ; SET TRANSFER LOCKING-SHIFT
  196.     mkeyw    'Off',lock_disable
  197.     mkeyw    'On',lock_enable
  198.     mkeyw    'Forced',lock_force
  199.  
  200. xfertab2 db    2            ; SET TRANSFER TRANSLATION
  201.     mkeyw    'Readable',0
  202.     mkeyw    'Invertible',1
  203.  
  204. xfertab3 db    2            ; SET TRANSFER MODE
  205.     mkeyw    'Automatic',1
  206.     mkeyw    'Manual',0
  207.  
  208. xfchtab    db    6            ; SET TRANSFER CHARACTER-SET
  209.     mkeyw    'Transparent',xfr_xparent    ; no translation
  210.     mkeyw    'Latin1 ISO 8859-1',xfr_latin1    ; ISO 8859-1, Latin-1
  211.     mkeyw    'Latin2 ISO 8859-2',xfr_latin2    ; ISO 8859-2, Latin-2
  212.     mkeyw    'Hebrew ISO 8859-8',xfr_hebiso    ; ISO 8859-8 Hebrew-ISO
  213.     mkeyw    'Cyrillic ISO 8859-5',xfr_cyrillic; ISO 8859-5/Cyrillic, CP866
  214.     mkeyw    'Japanese-EUC',xfr_japanese    ; Japanese-EUC
  215.  
  216. xftyptab db    2            ; SET FILE TYPE table
  217.     mkeyw    'Binary',1        ; Binary = as-is
  218.     mkeyw    'Text',0        ; Text = can change char sets
  219.  
  220. warntab    db    8            ; File Warning table
  221.     mkeyw    'Append',filecol_append        ; append
  222.     mkeyw    'Overwrite',filecol_overwrite    ; overwrite
  223.     mkeyw    'Rename',filecol_rename        ; rename
  224.     mkeyw    'Discard',filecol_discard    ; discard
  225.     mkeyw    'Update',filecol_update        ; update (if incoming is newer)
  226.     mkeyw    'No-supersede',filecol_discard    ; discard
  227.     mkeyw    'on (rename)',filecol_rename    ; old form
  228.     mkeyw    'off (overwrite)',filecol_overwrite ; old form
  229.  
  230. unkctab db    2            ; unknown character-set disposition
  231.     mkeyw    'Keep',0
  232.     mkeyw    'Cancel',1
  233.  
  234. atttab    db    7            ; SET ATTRIBUTES table
  235.     mkeyw    'Off',00ffh        ; all off
  236.     mkeyw    'On',10ffh        ; all on (high byte is on/off)
  237.     mkeyw    'Character-set',attchr    ; Character set
  238.     mkeyw    'Date-Time',attdate    ; Date and Time
  239.     mkeyw    'Length',attlen        ; Length
  240.     mkeyw    'Type',atttype        ; Type
  241.     mkeyw    'System-id',attsys    ; System
  242.  
  243. comtab    db    2            ; table of COM ports
  244.     mkeyw    'COM3',4        ; offset of COM3 address
  245.     mkeyw    'COM4',6        ; offset of COM4 address
  246.  
  247. cntltab    db    2            ; SET CONTROL table
  248.     mkeyw    'Prefixed',0        ; 0 = send with prefix
  249.     mkeyw    'Unprefixed',1        ; 1 = send as-is
  250.  
  251. stsrtb    db    10            ; Number of options
  252.     mkeyw    'Packet-length',srpack
  253.     mkeyw    'Padchar',srpad
  254.     mkeyw    'Padding',srnpd
  255.     mkeyw    'Pause',srpaus
  256.     mkeyw    'Start-of-packet',srsoh
  257.     mkeyw    'Quote',srquo
  258.     mkeyw    'End-of-packet',sreol
  259.     mkeyw    'Timeout',srtim
  260.     mkeyw    'Double-char',srdbl
  261.     mkeyw    'Pathnames',srpath
  262.  
  263. ontab    db    2
  264.     mkeyw    'off',0
  265.     mkeyw    'on',1
  266.  
  267. outputtab db    1            ; Set OUTPUT
  268.     mkeyw    'PACING',setopace
  269.  
  270. distab    db    5             ; Set Display mode
  271.     mkeyw    '7-bit',7        ; controls bit d8bit in flags.remflg
  272.     mkeyw    '8-bit',8        ; sets d8bit
  273.     mkeyw    'Quiet',dquiet        ; values defined in header file
  274.     mkeyw    'Regular',dregular
  275.     mkeyw    'Serial',dserial
  276.  
  277. distab2    db    3            ; for SET FILE DISPLAY
  278.     mkeyw    'Quiet',dquiet        ; values defined in header file
  279.     mkeyw    'Regular',dregular
  280.     mkeyw    'Serial',dserial
  281.  
  282. fossiltab db    1            ; Fossil
  283.     mkeyw    'disable-on-close',1
  284.  
  285. ; If abort when receiving files, can keep what we have or discard
  286. abftab    db    2
  287.     mkeyw    'Discard',1
  288.     mkeyw    'Keep',0
  289.  
  290. flotab    db    5
  291.     mkeyw    'none',0
  292.     mkeyw    'xon/xoff',1+2        ; both directions
  293.     mkeyw    'incoming-xon/xoff',2
  294.     mkeyw    'outgoing-xon/xoff',1
  295.     mkeyw    'RTS/CTS',4
  296.  
  297. FIFOtab    db    2
  298.     mkeyw    'FIFO-disabled',0
  299.     mkeyw    'FIFO-enabled',1
  300.  
  301. hndtab    db    8
  302.     mkeyw    'none',0
  303.     mkeyw    'bell',bell
  304.     mkeyw    'cr',cr
  305.     mkeyw    'esc',escape
  306.     mkeyw    'lf',lf
  307.     mkeyw    'xoff',xoff
  308.     mkeyw    'xon',xon
  309.     mkeyw    'code',0ffh        ; allow general numerial code
  310.  
  311. duptab    db    2            ; SET DUPLEX table
  312.     mkeyw    'full',0
  313.     mkeyw    'half',1
  314.  
  315. partab    db    6
  316.     mkeyw    'none',PARNON
  317.     mkeyw    'even',PAREVN
  318.     mkeyw    'odd',PARODD
  319.     mkeyw    'mark',PARMRK
  320.     mkeyw    'space',PARSPC
  321.     mkeyw    'HARDWARE',PARHARDWARE
  322. parhwtab db    4            ; for 9-bit bytes
  323.     mkeyw    'even',PAREVNH
  324.     mkeyw    'odd',PARODDH
  325.     mkeyw    'mark',PARMRKH
  326.     mkeyw    'space',PARSPCH
  327.  
  328. exittab    db    1            ; EXIT table
  329.     mkeyw    'warning',0
  330.  
  331. gettab    db    3            ; GETOK dispatch table
  332.     mkeyw    'Yes',kssuc        ; success = yes
  333.     mkeyw    'OK',kssuc        ; ditto
  334.     mkeyw    'No',ksgen        ; general failure
  335.  
  336. inptab    db    5                ; Scripts. Set Input
  337.     mkeyw    'Case',inpcas            ;[jrs]
  338.     mkeyw    'Default-timeout',inptmo    ;[jrs]
  339.     mkeyw    'Echo',inpeco            ;[jrs]
  340.     mkeyw    'Filter-echo',infilt
  341.     mkeyw    'Timeout-action',inpact        ;[jrs]
  342.  
  343. resettab db    1
  344.     mkeyw    'Clock',80h
  345.  
  346. macrotab db    1            ; SET MACRO table
  347. ;;    mkeyw    'Echo',0
  348.     mkeyw    'Error',1
  349.  
  350. pathtab    db    3            ; SET SEND/RECEIVE PATHNAMES
  351.     mkeyw    'off',0
  352.     mkeyw    'relative',1
  353.     mkeyw    'absolute',2
  354.  
  355. taketab    db    3            ; SET TAKE table
  356.     mkeyw    'Debug',2
  357.     mkeyw    'Echo',0
  358.     mkeyw    'Error',1
  359.  
  360. xmitab    db    4            ; SET TRANSMIT table
  361.     mkeyw    'Fill-empty-line',0
  362.     mkeyw    'Line-Feeds-sent',1
  363.     mkeyw    'Pause',3
  364.     mkeyw    'Prompt',2
  365.  
  366. debtab    db    4            ; Set Debug command
  367.     mkeyw    'Off',0
  368.     mkeyw    'On',logpkt+logses
  369.     mkeyw    'Packets',logpkt
  370.     mkeyw    'Session',logses
  371.  
  372. logtab    db    3            ; LOG command
  373.     mkeyw    'Packets',logpkt
  374.     mkeyw    'Session',logses
  375.     mkeyw    'Transactions',logtrn
  376.  
  377. srvdetab db    18            ; Enable/Disable list for server
  378.     mkeyw    'All',0ffffh
  379.     mkeyw    'BYE',byeflg
  380.     mkeyw    'CD',cwdflg
  381.     mkeyw    'CWD',cwdflg
  382.     mkeyw    'Define',defflg
  383.     mkeyw    'Delete',delflg
  384.     mkeyw    'Dir',dirflg
  385.     mkeyw    'Finish',finflg
  386.     mkeyw    'Get',getsflg
  387.     mkeyw    'Host',hostflg
  388.     mkeyw    'Kermit',kerflg
  389.     mkeyw    'Login',pasflg
  390.     mkeyw    'Print',prtflg
  391.     mkeyw    'Retrieve',retflg
  392.     mkeyw    'Query',qryflg
  393.     mkeyw    'Send',sndflg
  394.     mkeyw    'Space',0;;;spcflg    ; obsolete, non-functional
  395.     mkeyw    'Type',typflg
  396.  
  397. trnstab    db    2            ; Set Translation table
  398.     mkeyw    'Input',1
  399.     mkeyw    'Keyboard',2
  400.  
  401. ifndef    no_tcp
  402. tcptable db    14            ; Telnet or TCP/IP command
  403.     mkeyw    'address',1        ; local Internet address
  404.     mkeyw    'domain',2        ; local domain string
  405.     mkeyw    'broadcast',8        ; broadcast of all 0's or all 1's
  406.     mkeyw    'gateway',4        ; gateway address
  407.     mkeyw    'primary-nameserver',5    ; name servers
  408.     mkeyw    'secondary-nameserver',6
  409.     mkeyw    'subnetmask',3        ; our subnet mask
  410.     mkeyw    'host',7        ; host's IP name or IP number
  411.     mkeyw    'Packet-Driver-interrupt',9
  412.     mkeyw    'term-type',10        ; Options term type
  413.     mkeyw    'NewLine-mode',11     ; CR-NUL vs CRLF
  414.     mkeyw    'mode',13        ; NVT-ASCII or Binary
  415.     mkeyw    'mss',14        ; Max Segment Size
  416.     mkeyw    'debug-Options',12    ; debug Telnet Options
  417.  
  418. tcpmodetab db    2            ; TCP/IP Mode
  419.     mkeyw    'NVT-ASCII',0
  420.     mkeyw    'Binary',1
  421.  
  422. tcpdbtab db    4            ; TCP Debug modes
  423.     mkeyw    'off',0
  424.     mkeyw    'status',1
  425.     mkeyw    'timing',2
  426.     mkeyw    'on' 3
  427.  
  428. newlinetab db    3            ; TCP/IP Newline mode
  429.     mkeyw    'off',0
  430.     mkeyw    'on',1
  431.     mkeyw    'raw',2
  432.  
  433. domainbad db    cr,lf,'?Bad domain name, use is such as my.domain.name$'
  434. addressbad db    cr,lf,'?string is too long$'
  435. hostbad    db    cr,lf,'?Bad host, use IP name or IP number$'
  436.  
  437. tcpaddress db    'dhcp',(16-($-tcpaddress)) dup (0),0
  438. tcpsubnet  db    '255.255.255.0',(16-($-tcpsubnet)) dup (0),0
  439. tcpdomain  db    'unknown',(32-($-tcpdomain)) dup (0),0
  440. tcpgateway db    'unknown',(32-($-tcpgateway)) dup (0),0
  441. tcpprimens db    'unknown',(16-($-tcpprimens)) dup (0),0
  442. tcpsecondns db    'unknown',(16-($-tcpsecondns)) dup (0),0
  443. tcphost    db    (60 -($-tcphost)) dup (0),0
  444. tcpbcast db    '255.255.255.255',(16-($-tcpbcast)) dup (0),0
  445. tcpbtpserver db    17 dup (0)        ; bootp server (response)
  446. tcpport    dw    23            ; TCP port
  447. tcppdint dw    0            ; Packet Driver interrupt
  448. tcpttbuf db    32 dup (0),0        ; term-type-override buffer
  449. tcpnewline db    1            ; NewLine-Mode (default is on)
  450. tcpdebug db    0            ; Options debugging (0 is off)
  451. tcpmode db    0            ; NVT-ASCII is 0, Binary is 1
  452. tcpmss    dw    1460            ; MSS
  453. endif    ; no_tcp
  454.  
  455. ; MACRO DATA STRUCTURES mcctab
  456. mcclen    equ    macmax*10        ; length of mcctab
  457. mcctab    db    0            ; macro name table entries
  458.     db    mcclen dup (0)        ; room for macro structures
  459. ; END OF MACRO DATA STRUCTURES
  460.  
  461. ibmmac    db    'IBM '            ; startup IBM macro definition + space
  462.     db    'set timer on,set parity mark,set local-echo on,'
  463.     db    'set handshake xon,set flow none,',0    ; asciiz
  464. dialmac    db    '__DIAL '            ; "__DIAL "
  465.     db    'asg \%9 \v(carrier),set carr off,'
  466.     db    'output ATD\%1\%2\%3\%4\%5\%6\%7\%8\13,wait 90 CD,'
  467.     db    'asg \%8 \v(status),set carr \%9,end \%8,',0    ; asciiz
  468.  
  469.     even
  470. prmptr    dw    kerm            ; pointer to prompt
  471. tempptr    dw    0            ; pointer into work buffer
  472. domacptr dw    0            ; pointer to DO MAC string
  473. min    dw    0 
  474. max    dw    0 
  475. numerr    dw    0
  476. numhlp    dw    0
  477. temp    dw    0
  478. temp1    dw    0            ; Temporary storage
  479. temp2    dw    0            ; Temporary storage
  480. askecho db    0            ; ask's echo control flag
  481. deftemp    dw    0
  482. stkadr    dw    0    ; non-zero if replacement keyboard xlator present
  483. mccptr    dw    mcctab             ; ptr to first free byte in mcctab
  484. macptr    dw    0            ; temp to hold segment of string
  485. npages    dw    10             ; # of pages of scrolling on each side
  486. rollwidth dw    0            ; columns to roll back 80..207
  487. portirq    db    4 dup (0)        ; user specified IRQ's for COM1..4
  488. portfifo db    4 dup (1)        ; user specified FIFO for COM1..4
  489. takeerror db    0            ; Take Error (0 = off)
  490. macroerror db    0            ; Macro Error (0 = off)
  491. marray    dw    27 dup (0)        ; pointers to macro array mem areas
  492. arraybad db    cr,lf,'? Array size is too large, 32000 max$'
  493. hidetmp    db    0            ; 0..9 binary for hide prefix
  494.  
  495. forstr1    db    '_forinc ',0         ; append 'variable step'
  496. forstr2 db    ' if not > ',0        ; append 'variable end'
  497. forstartptr dw    0
  498. forendptr dw    0
  499. forstepptr dw    0
  500. forcmdsptr dw 0
  501. forbadname db    cr,lf,'?Not a variable name$'
  502. data    ends
  503.  
  504. data1    segment
  505. askhlp1    db    'Variable name  then  prompt string$'
  506. askhlp2    db    'Prompt string$'
  507. askhlp3    db    'Enter a line of text$'
  508. getokhlp db    'Optional prompt string$'
  509. filhlp    db    ' Output filename for the log$'
  510. forhlp    db    cr,lf,'FOR variable initial final increment'
  511.     db    ' {command,command,...}$'
  512. dishlp    db    cr,lf,' Quiet (no screen writing), Regular (normal),'
  513.     db    ' Serial (non-formatted screen)'
  514.     db    cr,lf,' and/or 7-BIT (default) or 8-BIT wide characters.$'
  515. exitwhlp db    cr,lf,' ON or OFF. Warn if sessions are active when exiting'
  516.     db    ' Kermit$'
  517. remhlp    db    cr,lf,' OFF to show file transfer display,'
  518.     db    ' ON for quiet screen$'
  519. macmsg    db    ' Specify macro name followed by body of macro, on same line$'
  520. prmmsg    db    cr,lf
  521.     db    ' Enter new prompt string or press Enter to regain default prompt.'
  522.     db    cr,lf,' Use \fchar(123) notation for special chars;'
  523.     db    ' Escape is \fchar(27).$'
  524. rspathhlp db    cr,lf,' OFF removes pathnames during file transfer,'
  525.     db    cr,lf,' RELATIVE includes path from current location'
  526.     db    cr,lf,' ABSOLUTE includes path from root of drive$'
  527.     
  528. srxhlp1    db    cr,lf,' Enter   code for received byte   code for'
  529.     db    ' local byte ',cr,lf,' use ascii characters themselves or'
  530.     db    cr,lf,' numerical equivalents of  \nnn  decimal'
  531.     db    ' or \Onnn  octal or \Xnnn  hexadecimal',cr,lf
  532.     db    ' or keywords  ON  or  OFF  (translation is initially off)'
  533.     db    cr,lf,'$'
  534.  
  535. takchlp    db    cr,lf,'Value 0 to 65535 for COUNT in script IF COUNT command$'
  536.  
  537. nummsg1 db    cr,lf,'?Use a number between $'
  538. nummsg2    db    ' and $'
  539. srvthlp    db    'seconds, 0-255, waiting for a transaction$'
  540. unkchhlp db    cr,lf,' Disposition of files arriving with unknown'
  541.     db    ' character sets:',cr,lf,'  Keep (default), Cancel$'
  542. winhelp    db    cr,lf,'Number of sliding window slots 1 (no windowing) to 32$'
  543. eophlp    db    ' Decimal number between 0 and 31$'
  544. ctlhlp    db    ' Decimal number between 0 and 31, 128 and 159$'
  545. cntlhlp db    cr,lf,' PREFIXED <0..31, 128..159> protectively quotes this'
  546.     db    ' control code',cr,lf
  547.     db    ' UNPREFIXED <0..31, 128..159> sends control code as-is'
  548.     db    cr,lf,' Use ALL to change all codes at once.$'
  549. sohhlp    db    ' Decimal number between 0 and 31.',cr,lf,' Special case:'
  550.     db    ' up to 126, but reduces strength of the protocol.$'
  551. dmphlp    db    ' Filename to hold screen dumps$'
  552. prnhlp    db    ' Filename for printer output (default is PRN)$'
  553. prnerr    db    cr,lf,' Cannot open that name. Using default of PRN$'
  554. erlhlp    db    ' Decimal number between 0 and 255$'
  555. pakerr    db    cr,lf,'?Choose a decimal number '
  556.     db    'from 20 to 94 (normal) or to 9024 (long)$'
  557. pakhlp    db    cr,lf,'Decimal number between 20 and 94 (normal) or '
  558.     db    '9024 (long)$'
  559. padhlp    db    cr,lf,' Decimal number between 0 and 31 or 127$'
  560. pauhlp    db    ' Decimal number between 0 and 65383 milliseconds$'
  561. quohlp    db    ' Decimal number between 33 and 126$'
  562. retryhlp db    ' Decimal number between 1 and 63$'
  563. rollhlp    db    ' Decimal number between 0 and 8000$'
  564. dblhlp    db    ' Decimal number between 0 and 255$'
  565. stophlp    db    ' Serial port stop bits, 1 (default) or 2$'
  566. luserh    db    cr,lf,'Username Password from remote Kermit (0-16 chars each)$'
  567. lpassh    db    cr,lf,'Password from remote Kermit (0-16 chars,'
  568.     db    ' spaces allowed)$'
  569. prefhlp    db    cr,lf,' single char (def is ~) or number between 33-62 or'
  570.     db    ' 96-126$'
  571. timhlp    db    ' Decimal number between 0 and 94$'
  572. delyhlp    db    ' Delay seconds before sending file (0-63)$'
  573. eschlp    db    cr,lf,'Press literal control keys (ex: Control ]) or'
  574.     db    ' enter in \nnn numerical form$'
  575. hnd1hlp    db    cr,lf,'XON (\17), XOFF (\19), CR (\13), LF (\10), BELL (\7),'
  576.     DB    ' ESC (\27), NONE (\0)'
  577.     db    cr,lf,' or "CODE" followed by decimal number$' 
  578. intoms    db    'number of seconds to wait before timeout',cr,lf,'$'
  579. loghlp    db    cr,lf
  580.     db    ' PACKETS - during file transfers  (to default file PACKET.LOG)'
  581.     db    cr,lf
  582.     db    ' SESSION - during Connect mode   (to default file SESSION.LOG)'
  583.     db    cr,lf
  584.     db    ' TRANSACTIONS - files transfers (to default file TRANSACT.LOG)'
  585.     db    cr,lf,'  followed by an optional filename for the log and'
  586.     db    ' optional',cr,lf,' '
  587. loghlp2    db    ' APPEND (default) or NEW$'
  588. carhlp    db    cr,lf,' ON or OFF. Sense modem Carrier Detect and end'
  589.     db    ' connection if it drops.$'
  590. comhlp    db    cr,lf,' Set port address, IRQ, and control UART FIFO.'
  591.     db    cr,lf,' Address of the COM1 - COM4 port (ex: COM3 \x02f8 or'
  592.     db    ' COM4 \x02e8)$'
  593. irqhlp    db    cr,lf,' IRQ of port (ex: \3)$'
  594. fifohlp db    cr,lf,' FIFO-disable or FIFO-enable or press Enter key.'
  595.     db    cr,lf,' FIFO-disable means bypass UART buffer$'
  596. debhlp    db    cr,lf,' PACKETS - during file transfers'    ; Debugging
  597.     db    cr,lf,' SESSION - during Connect mode'
  598.     db    cr,lf,' ON - both packets and session'
  599.     db    cr,lf,' OFF - turns off all debugging$'
  600. dialhlp    db    ' Phone number to dial$'
  601. dohlp    db    cr,lf,'definitions of variables (\%n), or press ENTER key$'
  602. fossilhlp db    cr,lf,' OFF to leave Fossil active (default), ON to disable'
  603.     db    ' when done with port$'
  604. sdshlp    db    cr,lf,'DISABLE or ENABLE access to selected Server commands:'
  605.     db    cr,lf
  606.     db    ' BYE (includes LOGOUT), CD/CWD, DEFINE, DEL, DIR, FINISH,'
  607.     db    ' GET, HOST,',cr,lf
  608.     db    ' KERMIT, LOGIN, PRINT, QUERY, RETRIEVE, SEND, TYPE,'
  609.     db    ' and ALL.$'
  610.  
  611. xfchhlp    db    cr,lf,' Which character set to put on the wire during file'
  612.     db    ' transfers:',cr,lf
  613.     db    '  TRANSPARENT (regular PC codes)',cr,lf
  614.     db    '  LATIN1    (ISO 8859-1)',cr,lf
  615.     db    '  LATIN2    (ISO 8859-2)',cr,lf
  616.     db    '  HEBREW    (ISO 8859-8)',cr,lf
  617.     db    '  CYRILLIC  (ISO 8859-5)',cr,lf
  618.     db    '  JAPANESE-EUC$'
  619. xferhlp1 db    cr,lf,' OFF: disable feature, ON: enable (default), FORCE:'
  620.     db    ' forced on$'
  621. xfchhlp2 db    cr,lf,' READABLE: translate some/many characters to/from'
  622.     db    ' locally readable form (def).'
  623.     db    cr,lf,' INVERTIBLE: use codes which can be copied back to the'
  624.     db    ' host in its form.$'
  625. xferhlp3 db    cr,lf,'Automatic (Binary mode between like systems),'
  626.     db    ' manual (default)$'
  627. xfilhlp    db    'NONE, SPACE, or filler character$'
  628. xpmthlp db    'Host echo char acting as prompt, \1-\255$'
  629. xpauhlp    db    'Millisec to pause between lines, 1 - 65000$'
  630. opacehlp db    'Millisec to pause between OUTPUT bytes, 0 - 65000$'
  631. pophlp    db    'Status value to be returned  msg, nothing if no new value$'
  632. sethlp    db    cr,lf
  633.     db    '  Alarm    sec from now or HH:MM:SS  '
  634.     db    '  Mode-line         on/off'
  635.     db    cr,lf
  636.     db    '  Attributes packets on/off          '
  637.     db    '  NetBios-name      (our local name)'
  638.     db    cr,lf
  639.     db    '  Bell    on/off    at end of xfers  '
  640.     db    '  Output pacing (ms between bytes)  '
  641.     db    cr,lf
  642.     db    '  Block-check-type  checksum/CRC     '
  643.     db    '  Parity    even/odd/mark/space/none'
  644.     db    cr,lf
  645.     db    '  Carrier  sense modem Carrier Detect'
  646.     db    '  Port (or Line)    1/2/COM1/COM2/etc'
  647.     db    cr,lf
  648.     db    '  COM1 - COM4 port-address irq       '
  649.     db    '  Printer filespec   for Connect mode'
  650.     db    cr,lf
  651.     db    '  Control prefixed/unprefixed  code  '
  652.     db    '  Prompt  string   (new Kermit prompt)'
  653.     db    cr,lf
  654.     db    '  Count   number    a loop counter   '
  655.     db    '  Receive parameter  many things'
  656.     db    cr,lf
  657.     db    '  Debug   on/off    display packets  '
  658.     db    '  Repeat Counts (on/off)             '
  659.     db    cr,lf
  660.     db    '  Default-disk                       '
  661.     db    '  Retry limit for packet send/receive'
  662.     db    cr,lf
  663.     db    '  Delay   secs  before Sending file  '
  664.     db    '  Rollback, terminal screens'
  665.     db    cr,lf
  666.     db    '  Destination   Disk/Screen/Printer  '
  667.     db    '  Send parameter    many things'
  668.     db    cr,lf
  669.     db    '  Display quiet/reg/serial show cnts?'
  670.     db    '  Server parameter'
  671.     db    cr,lf
  672.     db    '  Dump filespec     screen to disk   '
  673.     db      '  Speed or Baud     many speeds'    
  674.     db    cr,lf
  675.     db    '  Duplex            half or full     '
  676.     db    '  Streaming         on/off'
  677.     db    cr,lf
  678.     db    '  EOF Ctrl-Z/NoCtrl-Z  ^Z ends file? '
  679.     db    '  Stop-bits         always 1'
  680.     db    cr,lf
  681.     db     '  End-of-line char  cr or whatever   '
  682.     db    '  Take Echo or Error on/off' 
  683.     db    cr,lf
  684.     db    '  Errorlevel number   for DOS Batch  '
  685.     db    '  TCP/IP or Telnet  parameters'
  686.     db    cr,lf
  687.     db      '  Escape-char  ^]   or whatever      '
  688.     db    '  Terminal type and parameters'
  689.     db    cr,lf
  690.     db    '  Exit warning (if session active)   '
  691.     db    '  Timer     on/off  time packet waiting'
  692.     db    cr,lf
  693.     db    '  File (Character-set, Type, Warning)'
  694.     db    '  Translation in  Connect mode rcv''d char'
  695.     db    cr,lf
  696.     db    '  Flow-control  none xon/xoff rts/cts'
  697.     db    '  Transfer Character-set (on wire) '
  698.     db    cr,lf
  699.     db    '  Handshake xon/xoff/cr/lf/bell/esc..'
  700.     db    '  Transmit  parameters, for scripts'
  701.     db    cr,lf
  702.     db    '  Incomplete file   keep/discard     '
  703.     db    '  Unknown-character-set (keep/cancel)'
  704.     db    cr,lf
  705.     db    '  Input timeout, etc  (for scripts)  '
  706.     db    '  Warning   on/off  if file renamed'
  707.     db    cr,lf
  708.     db    '  Key         key-ident   definition '
  709.     db    '  Windows  number of sliding window slots'
  710.     db    cr,lf
  711.     db    '  Local-echo        on/off'
  712.     db    '$'
  713.  
  714. ifndef    no_tcp
  715. hosthlp    db    cr,lf,'Internet name or number (ddd.ddd.ddd.ddd) of '
  716.     db    'the remote machine$'
  717. domainhlp db    cr,lf,'Name of your domain$'
  718. subnethlp db    cr,lf,'Subnetmask, decimal ddd.ddd.ddd.ddd$'
  719. addrhelp db    cr,lf,'Internet address, decimal ddd.ddd.ddd.ddd, of this'
  720.     db    ' machine or'
  721.     db    cr,lf,' BOOTP, DHCP, RARP, or Telebit-PPP$'
  722. iphelp    db    cr,lf,'Internet address, decimal ddd.ddd.ddd.ddd$'
  723. tcppdinthlp db    cr,lf,'Interrupt on PC for Packet Driver, \x40 to \x7f'
  724.     db    ' or use 0 for automatic search,'
  725.     db    cr,lf,' or ODI to use Novell''s ODI interface$'
  726. tcpttyhlp db    cr,lf,' Telnet Options terminal identification override '
  727.     db    'string.'
  728.     db    cr,lf,' This does NOT modify the real terminal type.'
  729.     db    ' Press ENTER to remove this',cr,lf 
  730.     db    ' override and report the real terminal type.$'
  731. tcpnlhlp db    cr,lf,' ON sends CR LF for each CR, OFF sends CR NUL,'
  732.     db    ' RAW sends just CR$'
  733. tcpmsshlp db    cr,lf,' Maximum Segment Size, 16 to 1460 bytes$'
  734. endif    ; no_tcp
  735. arrayhlp db    ' \&<char>[size]   size of 0 undefines the array$'
  736.  
  737. data1    ends
  738.  
  739. code1    segment
  740.     extrn    makebuf:far, domath:far, strlen:far, strcpy:far
  741.     extrn    prtasz:far, decout:far, strcat:far, toupr:far
  742.     extrn    isfile:far, malloc:far, dec2di:far, takrd:far
  743.     assume     cs:code1
  744. code1    ends
  745.  
  746. code    segment
  747.     extrn comnd:near, baudst:near, prompt:near, coms:near, cwdir:near
  748.     extrn lnout:near, breakcmd:near
  749.     extrn vts:near, setalrm:near, serrst:near
  750.     extrn prnopen:near, pntflsh:near
  751. ifndef    no_network
  752.     extrn setnbios:near    ; in MSXIBM, needs stub for other machines
  753. endif    ; no_network
  754.     assume    cs:code, ds:data, es:nothing
  755.  
  756. ; DO defined macro command
  757. ; DO macname variable variable   also defines variables \%1, \%2, ...\%9
  758. DOCOM    PROC    NEAR
  759.     mov    dx,offset mcctab    ; table of macro defs
  760.     xor    bx,bx            ; help is table
  761.     mov    ah,cmkey        ; get key word (macro name)
  762.     call    comnd            ; get pointer to keyword structure
  763.     jnc    docom1            ; nc = success, bx = 16 bit data
  764.     ret                ; failure
  765. DOCOM1:    mov    domacptr,bx        ; segment of definition string
  766.     mov    comand.cmquiet,0    ; permit command echoing
  767.     mov    bx,offset decbuf+2    ; point to borrowed work buffer
  768. docom1a:mov    dx,offset dohlp        ; help
  769.     mov    comand.cmblen,decbuflen ; length of analysis buffer
  770.     mov    comand.cmdonum,1    ; \number conversion allowed
  771.     mov    ah,cmword
  772.     call    comnd
  773.     jnc    docom1b
  774.     ret
  775. docom1b:mov    si,bx            ; terminating null
  776.     sub    si,ax            ; minus length
  777.     mov    [si-2],ax        ; store length in preceeding word
  778.     add    bx,2            ; leave a full word empty
  779.     mov    word ptr [bx-2],0
  780.     or    ax,ax            ; any text?
  781.     jnz    docom1a            ; nz = got text, get more
  782.     mov    ah,cmline        ; read and discard rest of line
  783.     mov    bx,offset rdbuf        ; discard here
  784.     xor    dx,dx            ; no help
  785.     call    comnd
  786.     jnc    docom2            ; nc = success
  787.     ret
  788.  
  789. docom2:    inc    taklev            ; prepare for being in Take below
  790.     call    hidemac            ; hide previous \%0..\%9 macros
  791.     dec    taklev
  792.     call    getname            ; get name of this macro to rdbuf
  793.     mov    cx,word ptr rdbuf    ; length of "\%0 plus found name"
  794.     call    dodecom            ; define macro \%0 as macro name
  795.     jc    docomx            ; c = failure
  796.     push    es
  797.     mov    ax,domacptr        ; macro definition string segment
  798.     mov    es,ax            ; string is in es:si
  799.     xor    si,si            ; point to count word
  800.     call    docnv            ; convert macro string in-place
  801.     pop    es            ; to lift top {} and do bare "," -> CR
  802.     jc    docomx            ; c = failure
  803.  
  804.     mov    max,1            ; temp for counting 1 + number args
  805.     mov    word ptr rdbuf+4,' 1'    ; number of first variable
  806. docom3:    mov    word ptr rdbuf,0    ; clear length field, install \%x name
  807.     mov    word ptr rdbuf+2,'%\'    ; start with '\%1 '
  808.     mov    word ptr rdbuf+6,0    ; clear text field
  809.     mov    tempptr,offset rdbuf+6    ; pointer to location of found word
  810.     xor    ch,ch            ; make cx = 1 - 9
  811.     mov    cl,rdbuf+4        ; cx = word # of interest, for getwrd
  812.     sub    cl,'0'            ; remove ascii bias
  813.     mov    si,offset decbuf+2    ; source = work buffer (borrowed)
  814.     call    getwrd            ; get CX-th word from work buf (1-9)
  815.     cmp    deftemp,0        ; length of word, was it found?
  816.     je    docom4            ; e = no, end variable definition part
  817.     add    deftemp,4        ; count '\%n ' in command line length
  818.     inc    max            ; one more argument
  819.     mov    cx,deftemp        ; command length for dodecom
  820.     call    dodecom            ; add keyword+def using DEF MAC below
  821.     jc    docomx            ; c = failure
  822.     inc    rdbuf+4            ; inc number of variable in '\%n '
  823.     cmp    rdbuf+4,'9'
  824.     jbe    docom3            ; do '1' through '9', if available
  825.  
  826. docom4:    call    takopen_macro        ; create the DO the macro itself
  827.     jc    docomx            ; c = failure
  828.     mov    bx,takadr        ; point to current structure
  829.     push    es
  830.     mov    es,domacptr        ; segment of macro definition string
  831.     mov    [bx].takbuf,es        ; remember in Take structure
  832.     mov    cx,es:word ptr[0]    ; length of definition string
  833.     mov    si,cx
  834.     cmp    byte ptr es:[si+2-1],CR    ; terminates in CR?
  835.     je    docom5            ; e = yes
  836.     mov    byte ptr es:[si+2],CR    ; force CR termination
  837.     ; keeps open macro until after last command has executed, for \%digit
  838.     inc    cx            ; add CR to macro length
  839.     mov    es:[0],cx        ; update image too
  840. docom5:    pop    es
  841.     mov    [bx].takcnt,cx        ; # of unread chars in buffer
  842.     mov    cx,max            ; 1 + number of arguments
  843.     mov    [bx].takargc,cx
  844.     mov    al,taklev        ; Take level now
  845.     mov    [bx].takinvoke,al    ; remember take level of this DO
  846.     clc                ; success
  847.     ret
  848.  
  849. docomx:    inc    taklev            ; simulate Take closing
  850.     mov    hidetmp,0        ; unhide only \% args
  851.     call    unhidemac        ; recover hidden variables
  852.            dec    taklev
  853.     stc                ; say failure
  854.     ret
  855. DOCOM    ENDP
  856.  
  857. ; Extract CX-th word (cx = 1-9) from buffer (SI). Enter with si = source
  858. ; string and tempptr pointing at destination. Returns deftemp (count) of
  859. ; transferred characters.
  860. ; All registers preserved.
  861. getwrd    proc    near
  862.     push    si
  863.     push    di
  864.     push    es
  865.     push    cx            ; save word counter (1-9)
  866. getwr1:    mov    ax,[si-2]        ; get length of word
  867.     or    ax,ax
  868.     jz    getwr2            ; z = zero length, no word, quit
  869.     dec    cx            ; one less word
  870.     or    cx,cx
  871.     jz    getwr2            ; z = at desired word
  872.     add    si,ax            ; step to next word (<cnt><text>)
  873.     add    si,2            ; point to text
  874.     jmp    short getwr1
  875. getwr2:    mov    deftemp,ax        ; returned length of word
  876.     mov    cx,ax            ; length of word
  877.     mov    di,tempptr        ; where to store word/string
  878.     push    ds
  879.     pop    es            ; set es to data segment
  880.     cld
  881.     rep    movsb            ; copy bytes to destination
  882.     xor    al,al
  883.     stosb                ; force null terminator
  884.     pop    cx
  885.     pop    es
  886.     pop    di
  887.     pop    si
  888.     ret
  889. getwrd    endp
  890.  
  891. ; Get macro name, given the action pointer in domacptr.
  892. ; Return rdbuf as word:length that follows, then "\%0 macro-name"
  893. getname proc    near
  894.     push    bx
  895.     push    cx
  896.     push    dx
  897.     push    si
  898.     push    di
  899.     mov    dx,domacptr        ; action word to be matched
  900.     mov    bx,offset mcctab+1    ; table of macro names, skip count
  901.     mov    word ptr rdbuf,4    ; name length and space
  902.     mov    word ptr rdbuf+2,'%\'    ; define '\%0 '
  903.     mov    word ptr rdbuf+4,' 0'
  904.     mov    cl,mcctab        ; number of entries
  905.     xor    ch,ch
  906.     jcxz    getnam3            ; z = empty table
  907. getnam1:push    cx
  908.     mov    cx,[bx]            ; length of name
  909.     mov    si,bx            ; point at structure member
  910.     add    si,2            ; plus count
  911.     add    si,cx            ; plus length of name
  912.     mov    ax,[si]            ; get action word
  913.     cmp    ax,dx            ; correct action word?
  914.     jne    getnam2            ; ne = no
  915.     push    es
  916.     push    ds
  917.     pop    es
  918.     add    word ptr rdbuf,cx    ; length of macro \%0 + name
  919.     mov    di,offset rdbuf+6    ; where to store text
  920.     mov    si,bx
  921.     add    si,2            ; source of text
  922.     cld
  923.     rep    movsb            ; copy name to rdbuf+6
  924.     mov    byte ptr [di],0        ; null terminator
  925.     pop    es
  926.     pop    cx
  927.     jmp    short getnam3        ; exit
  928. getnam2:mov    ax,[bx]            ; get length of name
  929.     add    ax,4            ; plus count and word pointer
  930.     add    bx,ax            ; point to next entry
  931.     pop    cx
  932.     loop    getnam1            ; look at next entry
  933. getnam3:pop    di
  934.     pop    si
  935.     pop    dx
  936.     pop    cx
  937.     pop    bx
  938.     ret
  939. getname    endp
  940.  
  941. ; Local macro macro macro...  
  942. ; Hides existing macros of those names, if any
  943. localmac proc    near
  944.     cmp    taklev,0        ; in a take file/macro?
  945.     je    localmx            ; e = no, quit
  946.     mov    bx,offset rdbuf+2
  947.     xor    dx,dx            ; help
  948.     mov    comand.cmper,1        ; don't expand macro
  949.     mov    ah,cmword        ; get name of macro
  950.     call    comnd
  951.     jnc    localm1
  952. localmx:mov    ah,cmeol        ; get eol
  953.     call    comnd
  954.     ret
  955. localm1:mov    word ptr rdbuf,ax    ; save name length
  956.     or    ax,ax            ; empty (end of command)?
  957.     jz    localmx            ; z = yes, quit
  958.     mov    bx,offset mcctab+1    ; table of macro names, skip count
  959.     xor    ch,ch
  960.     mov    cl,mcctab        ; number of entries
  961.     jcxz    localmx            ; z = empty table
  962.  
  963. localm2:mov    ax,word ptr rdbuf    ; get user macro name length
  964.     cmp    word ptr [bx],ax    ; name length, same?
  965.     jne    localm4            ; ne = no, get next table entry
  966.     push    cx            ; compare names
  967.     push    si
  968.     push    di
  969.     mov    cx,ax            ; length of macro (either)
  970.     mov    si,offset rdbuf+2    ; user word
  971.     mov    di,bx            ; table word length
  972.     add    di,2            ; table word
  973. localm3:mov    al,[si]
  974.     mov    ah,[di]
  975.     inc    si
  976.     inc    di
  977.     call    toupr            ; upper case both
  978.     cmp    al,ah            ; same?
  979.     loope    localm3            ; e = yes
  980.     je    short localm5        ; e = fully matched
  981.     pop    di
  982.     pop    si
  983.     pop    cx
  984. localm4:mov    ax,[bx]            ; get length of name
  985.     add    ax,4            ; plus count and word pointer
  986.     add    bx,ax            ; point to next entry
  987.     loop    localm2            ; look at next table entry
  988.     jmp    localmac        ; get next macro name
  989.  
  990. localm5:pop    di
  991.     pop    si
  992.     pop    cx
  993.     mov    hidetmp,1        ; hide locals
  994.     call    hidewrk            ; hide macro pointed to by bx
  995.     jmp    localmac        ; get next macro name
  996. localmac endp
  997.  
  998.  
  999. ; DEFINE and ASSIGN macro commands
  1000. ; Data structures comments. Macro name is stored in table mcctab as if we
  1001. ; had used macro mkeyw, such as       mkeyw 'mymac',offset my_definition.
  1002. ; In detail:    dw    length of name
  1003. ;        db    'name'
  1004. ;        dw    segment:0 of definition string
  1005. ; Mcctab begins with a byte holding the number of macros in the table; one,
  1006. ;  IBM, is established at assembly time. Mcctab is 10*macmax bytes long.
  1007. ; Pointer mccptr holds the offset of the next free byte in mcctab.
  1008. ; Definition strings are stored in individually allocated memory as
  1009. ;        dw    length of definition string below
  1010. ;        db    'definition string'
  1011. ; A new definition is read into buffer rdbuf+2, where word rdbuf is reserved
  1012. ;  to hold the length of the macro's name during intermediate processing.
  1013. ; If the definition is absent then the macro is removed from the tables.
  1014. ;
  1015. ; ASSIGN is equivalent to DEFINE, except in the definition string substitution
  1016. ; variable names are expanded to their definitions.
  1017. ; DEFINE does not expand substitution variables.
  1018. ; Both commands will remove a first level curly brace pair if, and only if,
  1019. ; the definition begins and ends with them (trailing whitespace is allowed).
  1020. ; HIDE_ASSIGN and HIDE_DEFINE are like ASSIGN and DEFINE except the
  1021. ; destination name is expanded for substitution variables.
  1022. ;
  1023. HIDE_ASSIGN    proc    near
  1024.     mov    defkind,2        ; flag command as ASSIGN, vs DEFINE
  1025.     jmp    short dodefcom        ; common code
  1026. HIDE_ASSIGN    endp
  1027. HIDE_DEFINE    proc    near
  1028.     mov    defkind,3        ; flag command as DEFINE, vs ASSIGN
  1029.     jmp    short dodefcom        ; common code
  1030. HIDE_DEFINE    endp
  1031.  
  1032. ASSIGN    PROC    NEAR
  1033.     mov    defkind,0        ; flag command as ASSIGN, vs DEFINE
  1034.     jmp    short dodefcom        ; common code
  1035. ASSIGN    ENDP
  1036.  
  1037. UNDEFINE PROC    NEAR            ; undefine variable or array
  1038.     mov    defkind,4        ; bit 4 means undefine
  1039.     jmp    short dodefcom
  1040. UNDEFINE ENDP
  1041.  
  1042. DODEF    PROC    NEAR
  1043.     mov    defkind,1        ; flag command as DEFINE, vs ASSIGN
  1044. DODEFCOM:
  1045.     test    defkind,2        ; HIDE_assign/define?
  1046.     jnz    dodef0            ; nz = yes, expand destination
  1047.     mov    comand.cmper,1        ; do not react to '\%' in macro name
  1048. dodef0:    mov    ah,cmword
  1049.     mov    bx,offset rdbuf+2    ; buffer for macro name
  1050.     mov    word ptr rdbuf,0
  1051.     mov    comand.cmarray,1    ; allow sub in [..] of \&<char> arrays
  1052.     mov    comand.cmblen,length rdbuf-2 ; length of analysis buffer
  1053.     mov    dx,offset macmsg
  1054.     call    comnd            ; get macro name
  1055.     jnc    dodef1            ; nc = success
  1056.     ret                ; failure
  1057. dodef1:    or    ax,ax            ; null entry?
  1058.     jnz    dodef2            ; nz = no
  1059.     mov    dx,offset ermes6    ; more parameters needed
  1060.     jmp    reterr
  1061.  
  1062. dodef2:    mov    bx,offset rdbuf+2    ; start of string
  1063.     cmp    word ptr [bx],'%\'    ; \%<char> substitution variable?
  1064.     jne    dodef2b            ; ne = no
  1065.     cmp    ax,2            ; count, but missing <char>?
  1066.     ja    dodef2a            ; a = no
  1067.     mov    byte ptr [bx+2],'_'    ; slip in an underscore
  1068. dodef2a:mov    ax,3            ; limit to \%<char>, one char name
  1069.  
  1070. dodef2b:test    defkind,4        ; UNDEFINE?
  1071.     jz    dodef2c            ; z = no
  1072.     add    bx,ax            ; string length
  1073.     mov    word ptr [bx],0        ; create double null for defarray
  1074.     mov    comand.cmcnvkind,cmcnv_crprot ; allow CR within {..}
  1075.     mov    ah,cmeol        ; get eol, no definition string
  1076.     call    comnd
  1077.     jnc    dodef3            ; nc = success
  1078.     ret
  1079. dodef2c:add    bx,ax            ; point to string terminator
  1080.     mov    byte ptr [bx],' '    ; replace null with space separator
  1081.     inc    bx            ; where definition will start
  1082.     mov    ax,cmdblen        ; length of rdbuf
  1083.     sub    ax,2            ; skip initial count word
  1084.     add    ax,bx            ; next byte goes to bx
  1085.     sub    ax,offset rdbuf+2    ; amount of cmd line used
  1086.     mov    comand.cmblen,ax    ; our new buffer length
  1087.     mov    al,defkind        ; get ASSIGN/DEFINE flag
  1088.     and    al,1            ; pick out source flag bit
  1089.     mov    comand.cmper,al        ; react (ASSIGN) to '\%' in definition
  1090.     mov    comand.cmcnvkind,cmcnv_crprot ; allow CR within {..}
  1091.     mov    ah,cmline        ; get a line of text
  1092.     mov    dx,offset macmsg    ; help, bx is buffer offset
  1093.     call    comnd            ; get macro definition text
  1094.     jnc    dodef3            ; nc = success
  1095.     ret                ; failure
  1096. dodef3:    mov    dx,offset rdbuf+2
  1097.     call    strlen            ; length to cx
  1098.     jmp    short dodecom
  1099. DODEF    ENDP
  1100.  
  1101. ; Make a macro table entry and allocate buffer space.
  1102. ; Enter with rdbuf+2 et seq = <macro name><spaces><arg><spaces><arg> ...
  1103. ; and CX = byte count of line, starting at rdbuf+2.
  1104. ; Word rdbuf+0 computed here as length of keyword.
  1105. ; Allocates memory based on analyzed size of command line, returns memory
  1106. ; segment in macptr and in AX. Returns carry set if failure.
  1107. DODECOM    PROC    NEAR
  1108.     cmp    word ptr rdbuf+2,'&\'    ; dealing with arrays?
  1109.     jne    dode1            ; ne = no
  1110.     call    defarray        ; yes, do it in segment code1
  1111.     ret
  1112. dode1:    push    si            ; macro name in rdbuf+2 et seq
  1113.     push    di            ; cmd line length in deftemp
  1114.     push    es
  1115.     push    ds            ; address data segment
  1116.     pop    es
  1117.     push    deftemp
  1118.     mov    deftemp,cx        ; cmd line len, cx = running counter
  1119.     mov    rdbuf,0            ; number of chars in keyword so far
  1120.                     ; uppercase the keyword, look for end
  1121.     mov    si,offset rdbuf+2    ; point at macro name itself
  1122.     xor    dx,dx            ; a counter
  1123.     cld                ; strings go forward
  1124. dode2:    lodsb                ; get a byte
  1125.     cmp    al,'a'            ; map lower case to upper
  1126.     jb    dode3
  1127.     cmp    al,'z'
  1128.     ja    dode3
  1129.     sub    al,'a'-'A'
  1130.     mov    [si-1],al        ; uppercase if necessary
  1131. dode3:    inc    dx            ; increment char count of keyword
  1132.     cmp    al,' '            ; is this the break character?
  1133.     loopne    dode2            ; no, loop thru rest of word
  1134.     jne    dode4            ; ne = did not end with break char
  1135.     dec    dx            ; yes, don't count in length
  1136. dode4:    mov    di,offset rdbuf        ; point at mac name length
  1137.     mov    [di],dx            ; insert length in rdbuf
  1138.     push    dx            ; save length around call
  1139.     call    remtab            ; remove any duplicate keyword
  1140.                     ; check for free space for keyword
  1141.     pop    ax            ; keyword text length
  1142.     add    ax,4            ; plus count and word pointer
  1143.     add    ax,mccptr        ; add to free space pointer
  1144.     cmp    ax,offset mcctab+mcclen ; enough room for name?
  1145.     jb    dode5            ; b = yes
  1146.     mov    dx,offset ermes1    ; too many macro names
  1147.     pop    deftemp
  1148.     pop    es
  1149.     pop    di
  1150.     pop    si
  1151.     jmp    reterr
  1152.                     ; should be looking one byte after
  1153.                     ; space break char between name
  1154.                     ; and definition
  1155. dode5:    mov    dx,si            ; definition string
  1156.     call    strlen            ; get new length into cx
  1157.     jcxz    dode5c            ; z = no definition, exit this routine
  1158. dode5a: mov    al,[si]            ; read a definition byte
  1159.     cmp    al,','            ; leading COMMA?
  1160.     je    dode5b            ; e = yes, from {,cmd,cmd} stuff
  1161.     cmp    al,CR            ; leading CR?
  1162.     je    dode5b            ; e = yes, skip over it
  1163.     cmp    al,' '            ; leading space?
  1164.     jne    dode6            ; ne = no, have reached def text
  1165. dode5b:    inc    si            ; inc pointer, count down qty
  1166.     loop    dode5a            ; look again (note cx > 0 check above)
  1167. dode5c:    pop    deftemp            ; exit point with no definition left
  1168.     pop    es
  1169.     pop    di
  1170.     pop    si
  1171.     clc
  1172.     ret
  1173.  
  1174. dode6:    mov    deftemp,cx        ; remember definition length here
  1175.                     ; install new keyword
  1176.     jcxz    dode10            ; z = no def (should not happen here)
  1177.     mov    ax,cx            ; memory needed
  1178.     add    ax,2+1+1        ; plus count word and CR and saftey
  1179.     call    malloc
  1180.     jc    dode12            ; c = error, not enough memory
  1181. dode7:    mov    macptr,ax        ; store new segment
  1182.     mov    es,ax            ; segment of string
  1183.     xor    di,di            ; offset of count word
  1184.     mov    cx,deftemp        ; length of definition string
  1185.     mov    ax,cx
  1186.     cld
  1187.     stosw                ; store length of string
  1188.     rep    movsb            ; copy string
  1189.     mov    bx,offset mcctab    
  1190.     mov    dx,offset rdbuf        ; count word + name string
  1191.     call    addtab
  1192. dode10:    mov    ax,macptr        ; return buffer segment to caller
  1193.     pop    deftemp
  1194.     pop    es
  1195.     pop    di
  1196.     pop    si
  1197.     clc                ; success
  1198.     ret
  1199. dode12:    pop    deftemp            ; no memory, clean stack
  1200.     pop    es
  1201.     pop    di
  1202.     pop    si
  1203.     mov    dx,offset ermes2    ; no room for definition
  1204.     mov    ah,prstr
  1205.     int    dos
  1206.     stc
  1207.     ret
  1208. DODECOM    ENDP
  1209.  
  1210. DECLARE    proc    near        ; declare array \&<char @a..z>[size]
  1211.     mov    comand.cmper,1        ; do not react to '\&' in macro name
  1212.     mov    comand.cmdonum,1    ; \number conversion allowed
  1213.     mov    comand.cmarray,1    ; allow sub in [..]
  1214.     mov    ah,cmline
  1215.     mov    bx,offset rdbuf+2    ; buffer for macro name
  1216.     mov    comand.cmblen,length rdbuf-2 ; length of analysis buffer
  1217.     mov    dx,offset arrayhlp
  1218.     call    comnd            ; get macro name
  1219.     jnc    ndecl1            ; nc = success
  1220.     ret                ; failure
  1221. ndecl1:    call    fdeclare        ; call the far version
  1222.     ret
  1223. DECLARE endp
  1224.  
  1225. ; ASK <variable or macro name> <prompt string>
  1226. ; Defines indicated variable/macro with text from user at keyboard or pipe
  1227. ; (but not from a Take/macro). Prompt string is required.
  1228. ; ASKQ does the same, but does not echo user's response.
  1229. ASKQ    PROC    NEAR
  1230.     mov    askecho,1        ; temp to flag as Quiet version
  1231.     mov    temp,0
  1232.     jmp    short ask0        ; do common code
  1233. ASKQ    ENDP
  1234.  
  1235. GETC    PROC    NEAR
  1236.     mov    askecho,1
  1237.     mov    temp,1            ; signal as getc
  1238.     jmp    short ask0        ; do common code
  1239. GETC    ENDP
  1240.  
  1241. ASK    PROC    NEAR
  1242.     mov    askecho,0        ; temp to flag as echoing version
  1243.     mov    temp,0
  1244. ask0:                    ; common code for ASK and ASKQ
  1245.     mov    bx,offset decbuf+2    ; point to work buffer
  1246.     mov    word ptr decbuf,0
  1247.     mov    dx,offset askhlp1    ; help
  1248.     mov    comand.cmper,1        ; do not expand variable name
  1249.     mov    comand.cmarray,1    ; allow sub in [..] of \&<char> arrays
  1250.     mov    ah,cmword        ; get variable name
  1251.     call    comnd
  1252.     jnc    ask1            ; nc = success
  1253.     ret                ; failure
  1254. ask1:    or    ax,ax            ; anything given?
  1255.     jnz    ask2            ; nz = yes
  1256.     mov    dx,offset ermes6    ; more parameters needed
  1257.     jmp    reterr
  1258.  
  1259. ask2:    cmp    word ptr decbuf+2,'%\'    ; \%<char> substitution variable?
  1260.     jne    ask2b            ; ne = no
  1261.     cmp    ax,2            ; but missing <char>
  1262.     ja    ask2a            ; a = no
  1263.     mov    decbuf+4,'_'        ; slip in an underscore
  1264. ask2a:    mov    ax,3            ; limit to a single char
  1265. ask2b:    mov    bx,offset decbuf+2    ; start of name
  1266.     add    bx,ax            ; plus length of variable name
  1267.     mov    word ptr [bx],0+' '    ; put space+NULL separator after name
  1268.                     ; get ASK command prompt string
  1269.     mov    bx,offset decbuf+129    ; borrowed buffer for prompt
  1270.     mov    dx,offset askhlp2
  1271.     mov    comand.cmblen,127    ; our buffer length
  1272.     sub    comand.cmblen,ax    ;  minus part used above
  1273.     mov    comand.cmdonum,1    ; \number conversion allowed
  1274.     mov    comand.cmcr,1        ; bare cr's allowed (empty prompt)
  1275.     mov    ah,cmline        ; get prompt string
  1276.     call    comnd
  1277.     jnc    ask3            ; nc = success
  1278.     ret                ; failure
  1279. ask3:    push    ax
  1280.     mov    ah,cmeol
  1281.     call    comnd
  1282.     pop    ax
  1283.     jnc    ask4
  1284.     ret
  1285.  
  1286.     or    ax,ax            ; anything given?
  1287.     jnz    ask4            ; nz = yes
  1288.     mov    dx,offset ermes6    ; more parameters needed
  1289.     jmp    reterr
  1290.  
  1291. ask4:    mov    bx,offset decbuf+129
  1292.     add    bx,ax
  1293.     mov    word ptr [bx],0020h    ; printing terminator for prompt
  1294.     mov    comand.cmdirect,1    ; say read directly from kbd/file
  1295.     mov    dx,offset decbuf+129    ; converted prompt string, asciiz
  1296.      call    prompt            ; use our prompt
  1297.     mov    bx,offset rdbuf+129    ; use this buffer for raw user input
  1298.     mov    word ptr [bx],0        ; insert terminator
  1299.     mov    dl,askecho        ; get echo/quiet flag
  1300.     mov    comand.cmquiet,dl    ; 0 if echoing
  1301.     mov    dx,offset askhlp3    ; help for user input
  1302.     mov    comand.cmdirect,1    ; say read directly from kbd/file
  1303.     cmp    temp,1            ; getc?
  1304.     jne    ask8            ; ne = no
  1305. ask5:    mov    dl,0ffh
  1306.     mov    ah,dconio        ; read console
  1307.     int    dos
  1308.     jz    ask5            ; z = nothing there
  1309.     cmp    al,3            ; Control-C?
  1310.     jne    ask6            ; ne = no
  1311.     mov    flags.cxzflg,'C'    ; return Control-C status to parser
  1312.     stc                ; return error
  1313.     ret
  1314. ask6:    or    al,al            ; scan code being returned?
  1315.     jnz    ask7            ; nz = no, accept
  1316.     mov    ah,dconio        ; read and discard second byte
  1317.     mov    dl,0ffh
  1318.     int    dos
  1319.     mov    ah,conout        ; ring the bell
  1320.     mov    dl,bell
  1321.     int    dos
  1322.     jmp    short ask5        ; else unknown, ignore
  1323.  
  1324. ask7:    xor    ah,ah            ; null terminator
  1325.     cmp    al,'('            ; function delimiters?
  1326.     je    ask7a            ; e = yes
  1327.     cmp    al,')'
  1328.     je    ask7a            ; e = yes
  1329.     cmp    al,'{'            ; string delimiters?
  1330.     je    ask7a            ; e = yes
  1331.     cmp    al,'}'
  1332.     je    ask7a            ; e = yes
  1333.     cmp    al,DEL            ; this control?
  1334.     je    ask7a            ; e = yes
  1335.     cmp    al,' '            ; senstive (controls + space)?
  1336.     ja    ask7b            ; a = no
  1337. ask7a:    mov    rdbuf+129,'\'        ; numeric form prefix
  1338.     mov    di,offset rdbuf+130
  1339.     call    dec2di            ; convert to \decimal, asciiz
  1340.     clc
  1341.     jmp    short ask9
  1342. ask7b:    mov    word ptr rdbuf+129,ax    ; byte and terminator
  1343.     clc
  1344.     jmp    short ask9        ; process byte
  1345.  
  1346. ask8:    mov    ah,cmline        ; read user's input string
  1347.     mov    comand.cmper,1        ; do not expand variable names
  1348.     mov    comand.cmdonum,1    ; \number conversion allowed
  1349.     call    comnd
  1350. ask9:    mov    comand.cmquiet,0    ; permit echoing again
  1351.     mov    comand.cmdirect,0    ; read normally again
  1352.     jnc    ask10            ; nc = success
  1353.     ret                ; Control-C, quit now
  1354. ask10:    mov    cx,ax            ; length of entry
  1355.     mov    di,offset rdbuf+2
  1356.     mov    si,offset decbuf+2
  1357.     call    strcpy
  1358.     mov    dx,di
  1359.     call    strlen
  1360.     add    di,cx
  1361.     mov    si,offset rdbuf+129
  1362.     call    strcpy
  1363.      mov    dx,offset rdbuf+2    ; command buffer beginning
  1364.     call    strlen            ; CX=len of <variable>< ><user string>
  1365.     call    DODECOM            ; define the macro/variable and exit
  1366.     ret
  1367. ASK    ENDP
  1368.  
  1369. ; GETOK <prompt>   displays prompt or default prompt, asks for affirmative
  1370. ; user reply, returns success/fail status.
  1371. getok    proc    near
  1372.     mov    bx,offset rdbuf        ; point to work buffer
  1373.     mov    dx,offset getokhlp
  1374.     mov    comand.cmblen,127    ; our buffer length
  1375.     mov    comand.cmcr,1        ; bare cr is ok
  1376.     mov    comand.cmdonum,1    ; \number conversion allowed
  1377.     mov    ah,cmline        ; get prompt string
  1378.     mov    comand.cmcr,0
  1379.     call    comnd
  1380.     jnc    getok1            ; nc = success
  1381.     ret                ; failure
  1382. getok1:    or    ax,ax            ; anything given?
  1383.     jnz    getok2            ; nz = yes
  1384.     mov    si,offset getdef    ; default prompt
  1385.     mov    di,offset rdbuf
  1386.     call    strcpy            ; paste in default prompt
  1387.  
  1388. getok2:    mov    si,offset rdbuf
  1389.     mov    dx,si
  1390.     call    strlen            ; get length to cx
  1391.     mov    bx,cx
  1392.     mov    word ptr [si+bx],0020h    ; printing terminator for prompt
  1393. getok3:    mov    dx,offset rdbuf        ; converted prompt string, asciiz
  1394.     mov    comand.cmdirect,1    ; force input from kbd/file
  1395.      call    prompt            ; use our prompt
  1396.     mov    flags.cxzflg,0        ; clear Control-C indicator
  1397.     mov    dx,offset gettab    ; use this table
  1398.     xor    bx,bx            ; table is help
  1399.     mov    comand.cmcr,1        ; null response permitted
  1400.     mov    ah,cmkey        ; read user's input word
  1401.     call    comnd
  1402.     mov    comand.cmcr,0
  1403.     mov    comand.cmdirect,0    ; end force input from kbd/file
  1404.     jnc    getok4            ; nc = success
  1405.     cmp    flags.cxzflg,'C'    ; did user type Control-C to quit?
  1406.     jne    short getok3        ; ne = no, syntax failure, reprompt
  1407.     stc                ; set carry flag again
  1408.     jmp    short getok5        ; exit failure
  1409. getok4:    push    bx
  1410.     mov    comand.cmdirect,1    ; force input from kbd/file
  1411.     mov    ah,cmeol        ; get c/r confirmation
  1412.     call    comnd
  1413.     mov    comand.cmdirect,0    ; end force input from kbd/file
  1414.     pop    bx            ; recover keyword 16 bit value
  1415. getok5:    jnc    getok6            ; nc = success
  1416.     mov    kstatus,ksgen        ; failure
  1417.     ret                ; Control-C, quit now
  1418. getok6:    mov    kstatus,bx        ; return status
  1419.     ret
  1420. getok    endp
  1421.  
  1422. ; FOR macro-name start end step {commands}
  1423. FORCMD    proc    near
  1424.     mov    kstatus,ksgen        ; general command failure
  1425.     mov    ah,cmword        ; macro name
  1426.     mov    bx,offset decbuf
  1427.     mov    dx,offset forhlp    ; help
  1428.     mov    comand.cmper,1        ; don't react to \%x variables
  1429.     call    comnd
  1430.     jnc    for1            ; nc = success
  1431. forx:    mov    ah,cmeol        ; consume and discard the rest
  1432.     call    comnd
  1433.     stc
  1434.     ret                ; failure
  1435. for1:    cmp    word ptr decbuf,'%\'    ; start of variable name?
  1436.     jne    for2            ; ne = no
  1437.     cmp    ax,3            ; only three chars in name?
  1438.     je    for3            ; e = yes, we have \%<char>
  1439. for2:    mov    dx,offset forbadname
  1440.     mov    ah,prstr
  1441.     int    dos
  1442.     jmp    short forx
  1443. for3:    mov    bx,offset decbuf+4     ; where 'start' begins
  1444.     mov    forstartptr,bx         ; remember where 'start' begins
  1445.     mov    dx,offset forhlp
  1446.     mov    ah,cmword        ; get 'start'
  1447.     call    comnd
  1448.     jc    forx            ; c = failure
  1449.     mov    bx,forstartptr        ; 'start'
  1450.     call    todigits        ; convert to string of digits
  1451.     mov    dx,offset forhlp
  1452.     jc    forx            ; c = failure
  1453.     inc    bx            ; leave null terminator intact
  1454.     mov    forendptr,bx        ; 'end' starts here
  1455.     mov    dx,offset forhlp
  1456.     mov    ah,cmword        ; get 'end'
  1457.     call    comnd
  1458.     jc    forx            ; c = failure
  1459.     mov    bx,forendptr        ; 'end' string
  1460.     call    todigits        ; convert to string of digits
  1461.     jc    forx            ; c = failure
  1462.     inc    bx            ; leave null terminator intact
  1463.     mov    forstepptr,bx        ; 'step' starts here
  1464.     mov    dx,offset forhlp
  1465.     mov    ah,cmword        ; get 'step'
  1466.     call    comnd
  1467.     jc    forx            ; c = failure
  1468.     mov    bx,forstepptr
  1469.     mov    cl,[bx]            ; get possible minus sign on step
  1470.     mov    byte ptr temp,cl    ; save for bottom of this work
  1471.     call    todigits        ; convert to string of digits
  1472.     jc    forx            ; c = failure
  1473.     inc    bx            ; leave null terminator intact
  1474.     mov    forcmdsptr,bx        ; commands start here
  1475.     mov    dx,offset forhlp
  1476.     mov    comand.cmper,1        ; don't react to \%x variables
  1477.     mov    comand.cmblen,cmdblen    ; allow long lines
  1478.     mov    comand.cmcnvkind,cmcnv_crprot ; allow CR within {..}
  1479.     mov    ah,cmline        ; get {commands}
  1480.     call    comnd
  1481.     jc    forx            ; c = failure
  1482. ; At this point decbuf looks like this:
  1483. ; <string variable name><byte null><string end><byte null>
  1484. ;  <string step><byte null><string commands><byte null>
  1485.  
  1486. for4:                    ; define variable<space><start>
  1487.     mov    si,offset decbuf    ; start of variable name
  1488.     mov    di,offset rdbuf+2
  1489.     call    strcpy            ; variable name
  1490.     mov    dx,di
  1491.     call    strlen            ; length to cx for dodecom
  1492.     add    di,cx
  1493.     mov    byte ptr [di],' '    ; space
  1494.     inc    di            ; look at next byte
  1495.     push    di            ; where number is formed
  1496.     mov    si,forstartptr
  1497.     call    strcpy            ; copy start
  1498.     mov    dx,di
  1499.     call    strlen
  1500.     add    dx,cx            ; point at terminating null
  1501.     mov    di,dx
  1502.     mov    word ptr [di],'-'    ; minus, null
  1503.     mov    si,forstepptr        ; step
  1504.     call    strcat            ; append, have (start - step)
  1505.     pop    di
  1506.  
  1507.     mov    dx,di
  1508.     mov    domath_ptr,dx
  1509.     call    strlen
  1510.     mov    domath_cnt,cx
  1511.     call    domath            ; math to dx:ax
  1512.     push    word ptr decbuf
  1513.     push     word ptr decbuf+2    ; preserve variable name \%c 
  1514.     call    lnout            ; DX:AX to DS:DI as ASCII digits
  1515.     pop    word ptr decbuf+2    ; retore variable around work
  1516.     pop    word ptr decbuf
  1517.     mov    dx,offset rdbuf+2    ; buffer for dodecom
  1518.     call    strlen            ; length to cx for dodecom
  1519.     call    dodecom            ; define macro<space>start<null>
  1520.     mov    si,offset forstr1    ; build composite command string
  1521.     mov    di,offset rdbuf+2    ; starting at rdbuf+2
  1522.     call    strcpy            ; 'forinc '
  1523.     mov    si,offset decbuf    ; 'variable'
  1524.     call    strcat
  1525.     mov    si,offset space        ; space null
  1526.     call    strcat
  1527.     mov    si,forstepptr        ; 'step'
  1528.     call    strcat
  1529.     mov    si,offset forstr2    ; cr,'if not > '
  1530.     call    strcat
  1531.     cmp    byte ptr temp,'-'    ; negative step?
  1532.     jne    for4a            ; ne = no
  1533.     mov    dx,offset rdbuf+2
  1534.     call    strlen
  1535.     add    dx,cx            ; points at trailing null
  1536.     mov    si,dx
  1537.     mov    byte ptr [si-2],'<'    ; reverse sense of test for neg step
  1538. for4a:    mov    si,offset decbuf    ; 'variable'
  1539.     call    strcat
  1540.     mov    si,offset space        ; space null
  1541.     call    strcat
  1542.     mov    si,forendptr        ; 'end'
  1543.     call    strcat
  1544.     mov    si,offset space        ; space null
  1545.     call    strcat
  1546.     mov    si,forcmdsptr        ; 'commands'
  1547.     call    strcat
  1548.  
  1549.     mov    dx,offset rdbuf+2    ; string is built at rdbuf+2
  1550.     call    strlen
  1551.     mov    ax,cx            ;
  1552.     add    ax,2+1            ; bytes needed plus ending CR
  1553.     call    malloc
  1554.     mov    es,ax            ; seg
  1555.     mov    di,2            ; start two bytes in
  1556.     mov    si,offset rdbuf+2
  1557.     push    cx
  1558.     cld
  1559.     rep    movsb            ; copy from rdbuf+2 to malloc'd area
  1560.     pop    cx
  1561.     mov    al,CR
  1562.     stosb
  1563.     inc    cx            ; count CR in macro
  1564.     call    takopen_macro        ; open a macro
  1565.     mov    bx,takadr        ; point to current macro structure
  1566.     mov    ax,es            ; segment of definition
  1567.     mov    [bx].takbuf,ax        ; segment of definition string struc
  1568.     mov    [bx].takcnt,cx        ; number of chars in definition
  1569.     mov    es:[0],cx        ; buffer usage, for rewinding
  1570.     mov    [bx].takargc,0        ; our argument count
  1571.     mov    [bx].takptr,2        ; offset to read next command char
  1572.     or    [bx].takattr,take_malloc ; free buffer when done
  1573.     or    [bx].takattr,take_while
  1574.     clc
  1575.     ret
  1576. FORCMD    endp
  1577.  
  1578. ; Perform "inc variable step" from first two command line words
  1579. _forinc proc    near
  1580.     mov    ah,cmword        ; read variable name
  1581.     mov    comand.cmper,1        ; don't expand variable names here
  1582.     mov    bx,offset rdbuf+2    ; buffer
  1583.     xor    dx,dx            ; no help
  1584.     call    comnd
  1585.     jc    forincx            ; c = failure
  1586.     
  1587.     mov    word ptr rdbuf,ax    ; save length of macro name
  1588.     mov    si,offset mcctab    ; table of macro names
  1589.     cld
  1590.     lodsb
  1591.     xor    ch,ch
  1592.     mov    cl,al            ; number of macro entries
  1593.     or    al,al
  1594.     jnz    forinc4            ; nz = have some
  1595. forincx:mov    ah,cmeol        ; kill rest of line
  1596.     mov    comand.cmcnvkind,cmcnv_crprot ; allow CR within {..}
  1597.     call    comnd
  1598.     stc
  1599.     ret
  1600.                     ; find variable
  1601. forinc4:push    cx            ; save loop counter
  1602.     lodsw                ; length of macro name to ax
  1603.     mov    cx,word ptr rdbuf    ; length of user's string
  1604.     cmp    ax,cx            ; variable name same as user spec?
  1605.     jne    forinc6            ; ne = no, no match
  1606.     push    ax
  1607.     push    si            ; save these around match test
  1608.     mov    di,offset rdbuf+2    ; user's string
  1609. forinc5:mov    ah,[di]
  1610.     inc    di
  1611.     lodsb                ; al = mac name char, ah = user char
  1612.     and    ax,not 2020h        ; clear bits (uppercase chars)
  1613.     cmp    ah,al            ; same?
  1614.     loope    forinc5            ; while equal, do more
  1615.     pop    si            ; restore regs
  1616.     pop    ax
  1617.     jne    forinc6            ; ne = no match
  1618.     pop    cx            ; remove loop counter
  1619.     jmp    short forinc7        ; e = match
  1620. forinc6:add    si,ax            ; point to next name, add name length
  1621.     add    si,2            ;  and string pointer
  1622.     pop    cx            ; recover loop counter
  1623.     loop    forinc4            ; one less macro to examine
  1624.     jmp    forincx            ; failed to locate
  1625.  
  1626. forinc7:mov    ax,[si-2]        ; get length of variable string
  1627.     add    si,ax            ; point to segment of definition
  1628.     mov    si,[si]            ; seg of definition
  1629.     push    es
  1630.     mov    es,si
  1631.     mov    cx,es:[0]        ; length of definition
  1632.     mov    di,offset rdbuf+2    ; variable name from user
  1633.     add    di,[di-2]        ; plus length of variable name
  1634.     mov    byte ptr [di],' '    ; <count><varname><space>
  1635.     inc    di
  1636.     mov    si,2            ; skip over definition count word
  1637. forinc9:mov    al,es:[si]        ; copy string to regular data segment
  1638.     mov    [di],al
  1639.     inc    si
  1640.     inc    di
  1641.     loop    forinc9
  1642.     pop    es
  1643.  
  1644.     mov    byte ptr [di],'+'
  1645.     inc    di
  1646.     push    di            ; save place after '+'
  1647.     mov    bx,di            ; optional step goes here
  1648.  
  1649.     mov    ah,cmword        ; get step size, if any
  1650.     xor    dx,dx            ; no help at this level
  1651.     call    comnd
  1652.     pop    di
  1653.     jc    forincx            ; c = fail
  1654.                     ; now convert step size, if any
  1655.     or    ax,ax            ; is length zero?
  1656.     jnz    forinc15        ; nz = no, convert number to binary
  1657.     mov    word ptr [di],'1'    ; put '1' where optional is missing
  1658.  
  1659. forinc15:
  1660.     mov    di,offset rdbuf+2    ; user's variable name
  1661.     add    di,[di-2]        ; its length
  1662.     inc    di            ; skip space separator
  1663.     push    di            ; save for place to write result
  1664.     mov    dx,di
  1665.     call    strlen            ; get string length
  1666.     mov    domath_cnt,cx
  1667.     mov    domath_ptr,dx
  1668.     call    domath            ; convert to number in dx:ax
  1669.     cmp    domath_cnt,0        ; converted whole word?
  1670.     pop    di            ; clean stack
  1671.     jne    forincx            ; ne = no, fail
  1672.                     ; step size is in ax
  1673.     or    dx,dx            ; is result negative?
  1674.     jns    forinc16        ; ns = no, positive or zero
  1675.     neg    dx            ; flip sign
  1676.     neg    ax
  1677.     sbb    dx,0
  1678.     mov    byte ptr [di],'-'    ; show minus sign
  1679.     inc    di
  1680. forinc16:call    lnout            ; binary to ascii decimal in ds:di
  1681.     mov    dx,offset rdbuf+2    ; place of <var><space><value>
  1682.     call    strlen            ; length to cx for dodecom
  1683.     call    dodecom            ; re-define variable
  1684.     clc                ; return to let rest of cmd execute
  1685.     ret                ; as an IF statement
  1686. _forinc endp
  1687.  
  1688. ; Convert numeric expression to string of digits as a replacement, asciiz.
  1689. ; Enter with BX=start of expression, AX= length of expression.
  1690. ; Returns BX=null at end of number and carry clear if success,
  1691. ; or carry set and no change if failure
  1692. todigits proc    near
  1693.     mov    domath_ptr,bx        ; source text
  1694.     mov    domath_cnt,ax        ; length
  1695.     call    domath
  1696.     jnc    todigits1        ; nc = converted value
  1697.     ret                ; fail
  1698. todigits1:
  1699.     push    di
  1700.     mov    di,bx            ; where to write
  1701.     or    dx,dx            ; is result negative?
  1702.     jns    todigits2        ; ns = no, positive or zero
  1703.     neg    dx            ; flip sign
  1704.     neg    ax
  1705.     sbb    dx,0
  1706.     mov    byte ptr [di],'-'    ; show minus sign
  1707.     inc    di
  1708. todigits2:
  1709.     call    lnout            ; convert DX:AX to ASCIIZ in DS:DI
  1710.     mov    bx,di            ; point to trailing null
  1711.     pop    di
  1712.     clc                ; success
  1713.     ret
  1714. todigits endp
  1715.  
  1716. ; Initialize macro IBM at Kermit startup time
  1717. initibm    proc    near
  1718.     mov    si,offset ibmmac    ; text of IBM macro
  1719.     mov    di,offset rdbuf+2    ; where command lines go
  1720.     call    strcpy            ; copy it there
  1721.     mov    dx,di            ; get length of command line
  1722.     call    strlen            ; set cx to length, for dodecom
  1723.     call    dodecom            ; now define the macro
  1724.     mov    rdbuf+2,0
  1725.     mov    si,offset dialmac
  1726.     mov    di,offset rdbuf+2
  1727.     call    strcpy
  1728.     mov    dx,di
  1729.     call    strlen
  1730.     inc    cx
  1731.     jmp    dodecom            ; now define the macro
  1732. initibm    endp
  1733.  
  1734. ; Open an text subsititution macro. No buffer is allocated.
  1735. takopen_sub    proc    far
  1736.     cmp    taklev,maxtak        ; room in take level?
  1737.     jb    takosub1        ; b = yes
  1738.     mov    dx,offset ermes4    ; say too many Take files
  1739.     mov    ah,prstr        ; display error message
  1740.     int    dos
  1741.     stc                ; set carry for failure
  1742.     ret
  1743.  
  1744. takosub1:push    ax
  1745.     push    bx
  1746.     mov    bx,takadr        ; previous take structure
  1747.     push    [bx].takargc        ; stash argument count
  1748.     push    [bx].takctr        ; stash COUNT
  1749.     add    takadr,size takinfo    ; pointer to new Take structure
  1750.     inc    taklev
  1751.     mov    bx,takadr        ; pointer to new Take structure
  1752.     pop    [bx].takctr        ; copy in old count
  1753.     pop    [bx].takargc        ; copy in old argc
  1754.     xor    ax,ax
  1755.     mov    [bx].takbuf,ax        ; seg of memory block
  1756.     mov    [bx].takptr,2        ; where to read first
  1757.     mov    [bx].takcnt,ax        ; unread bytes in buffer
  1758.     mov    [bx].takper,al        ; expand macros
  1759.     mov    [bx].takattr,al        ; attribute, none
  1760.     mov    [bx].taktyp,take_sub    ; kind is text substitution
  1761.     mov    [bx].takinvoke,0
  1762.     pop    bx
  1763.     pop    ax
  1764.     clc
  1765.     ret
  1766. takopen_sub    endp
  1767.  
  1768. ; Open take structure for file input. Buffer of tbufsiz is preallocated
  1769. ; and pointed to by takbuf:takptr.
  1770. takopen_file    proc    far
  1771.     call    takopen_sub        ; do substitution macro busy work
  1772.     jnc    takofil1        ; nc = success so far
  1773.     ret                ; fail
  1774. takofil1:push    bx
  1775.     mov    bx,takadr
  1776.     mov    ax,tbufsiz        ; size of buffer
  1777.     call    malloc
  1778.     jnc    takofil2        ; nc = success
  1779.     pop    bx
  1780.     ret                ; fail
  1781.  
  1782. takofil2:mov    [bx].takbuf,ax        ; seg of allocated buffer
  1783.     mov    [bx].takattr,take_malloc ; remember so takclos will free it
  1784.     mov    [bx].taktyp,take_file    ; disk file kind
  1785.     mov    [bx].takhnd,0        ; file handle
  1786.     mov    word ptr [bx].takseek,0
  1787.     mov    word ptr [bx].takseek+2,0 ; seek distance, bytes
  1788.     or    [bx].takattr,take_autocr ; need auto CR at EOF
  1789.     mov    [bx].takinvoke,0
  1790.     pop    bx
  1791.     clc
  1792.     ret
  1793. takopen_file    endp
  1794.  
  1795. ; Open an internal (macro) structure. No buffer is allocated.
  1796. ; Return carry clear for success, carry set for failure.
  1797.  
  1798. takopen_macro    proc    far
  1799.     push    ax
  1800.     push    bx
  1801.     push    cx
  1802.     push    dx
  1803.     cmp    taklev,maxtak        ; room in take level?
  1804.     jb    takoma1            ; b = yes
  1805.     mov    dx,offset ermes4    ; say too many Take files
  1806.     mov    ah,prstr        ; display error message
  1807.     int    dos
  1808.     stc                ; set carry for failure
  1809.     jmp    takoma2
  1810.  
  1811. takoma1:xor    ax,ax
  1812.     add    takadr,size takinfo    ; pointer to new Take structure
  1813.     inc    taklev
  1814.     mov    bx,takadr        ; pointer to new Take structure
  1815.     mov    [bx].takargc,ax        ; clear
  1816.     mov    [bx].takctr,ax        ; clear
  1817.     mov    [bx].takbuf,ax        ; no segment of Take buffer
  1818.     mov    [bx].takcnt,ax        ; number of unread bytes
  1819.     mov    [bx].takptr,2        ; init pointer to definition itself
  1820.     mov    [bx].takper,al        ; expand macros
  1821.     mov    [bx].takattr,take_autocr ; need auto CR at EOF
  1822.     mov    [bx].taktyp,take_macro    ; macro
  1823.     mov    [bx].takinvoke,0
  1824.     clc                ; carry clear for success
  1825. takoma2:pop    dx
  1826.     pop    cx
  1827.     pop    bx
  1828.     pop    ax
  1829.     ret
  1830. takopen_macro endp
  1831.  
  1832. ; Close Take file. Enter at Take level to be closed.
  1833. ; Closes disk file, pops Take level.
  1834.  
  1835. TAKCLOS    PROC    FAR
  1836.     cmp    taklev,0        ; anything to close?
  1837.     jg    takclo1            ; g = yes
  1838.     ret
  1839. takclo1:push    ax
  1840.     push    bx
  1841.     push    cx
  1842.     mov    bx,takadr
  1843.     test    [bx].takattr,take_malloc ; new malloc'd buffer in takbuf?
  1844.     jz    takclo2            ; z = no
  1845.     mov    ax,[bx].takbuf
  1846.     push    es
  1847.     mov    es,ax            ; seg of separately malloc'd buffer
  1848.     mov    ah,freemem        ; free it
  1849.     int    dos
  1850.     pop    es
  1851.     and    [bx].takattr,not take_malloc ; no extra buffer to free
  1852. takclo2:mov    al,[bx].taktyp
  1853.     cmp    al,take_macro        ; macro?
  1854.     je    takclo3            ; e = yes
  1855.     cmp    al,take_file        ; disk file?
  1856.     jne    takclo6            ; ne = no, leaves sub and comand kinds
  1857.     mov    word ptr [bx].takseek,0    ; disk file
  1858.     mov    word ptr [bx].takseek+2,0 ; seek distance, bytes
  1859.     mov    bx,[bx].takhnd        ; get file handle
  1860.     mov    ah,close2        ; close file
  1861.     int    dos
  1862.  
  1863.                     ; macros, remove argument array
  1864. takclo3:cmp    [bx].takargc,0        ; any arguments to macro?
  1865.     je    takclo5            ; e = no
  1866.     mov    word ptr settemp,3    ; remove \%0..9 macros. length word
  1867.     mov    word ptr settemp+2,'%\'    ; "\%digit"
  1868.     mov    settemp+4,'0'
  1869. takclo4:mov    di,offset settemp    ; buffer remtab reads
  1870.     call    remtab            ; remove macro
  1871.     inc    settemp+4        ; next digit
  1872.     cmp    settemp+4,'9'        ; done last?
  1873.     jbe    takclo4            ; be = no
  1874. takclo5:mov    hidetmp,1        ; unhide local
  1875.     call    unhidemac        ; rename previous hidden macros
  1876.     mov    hidetmp,0        ; unhide \% args
  1877.     call    unhidemac        ; rename previous hidden macros
  1878.  
  1879. takclo6:mov    bx,takadr        ; all kinds of Take
  1880.     xor    al,al            ; get a null
  1881.     mov    [bx].taktyp,al        ; clear to avoid confusion
  1882.     mov    [bx].takper,al        ; macro expansion flag
  1883.     mov    [bx].takattr,al        ; attributes
  1884.     dec    taklev            ; pop macro Take level
  1885.     sub    takadr,size takinfo    ; get previous Take's address
  1886.     pop    cx
  1887.     pop    bx
  1888.     pop    ax
  1889.     ret
  1890. TAKCLOS    ENDP
  1891.  
  1892. ; POP/END command. Defend against command parser closing the Take/Macro at
  1893. ; the end of file. Return optional trailing number in ERRORLEVEL (errlev).
  1894. POPCMD    proc    near
  1895.     mov    oldifelse,0        ; don't permit ELSE after failed IF
  1896.     mov    ifelse,0
  1897.     mov    ah,cmword        ; get optional error value and msg
  1898.     mov    bx,offset rdbuf+2
  1899.     mov    dx,offset pophlp    ; help on numerical argument
  1900.     mov    comand.cmcr,1        ; bare c/r's allowed
  1901.     call    comnd
  1902.     mov    word ptr rdbuf,ax    ; save length here
  1903.     mov    comand.cmcr,0        ; restore normal state
  1904.     jc    popcmdx            ; c = failure
  1905.     mov    ah,cmline        ; get optional error value and msg
  1906.     mov    bx,offset rdbuf+100
  1907.     mov    dx,offset pophlp    ; help on numerical argument
  1908.     mov    comand.cmcr,1        ; bare c/r's allowed
  1909.     mov    comand.cmdonum,1    ; \number conversion allowed
  1910.     call    comnd
  1911.     mov    comand.cmcr,0        ; restore normal state
  1912.     jc    popcmdx            ; c = failure
  1913.     mov    domath_ptr,offset rdbuf+2
  1914.     mov    ax,word ptr rdbuf    ; get length of string
  1915.     mov    domath_cnt,ax
  1916.     call    domath            ; convert to number in ax
  1917.     jc    popcmd2            ; c = not a number
  1918.     mov    errlev,al        ; return value in ERRORLEVEL
  1919.     mov    kstatus,ax        ; and in STATUS
  1920.     mov    si,offset rdbuf+100
  1921. popcmd1:lodsb                ; read a msg char
  1922.     or    al,al            ; null terminator?
  1923.     jz    popcmd2            ; z = empty string
  1924.     cmp    al,' '            ; leading white space?
  1925.     je    popcmd1            ; be = leading white space
  1926.     dec    si            ; backup to non-white char
  1927.     mov    dx,offset crlf
  1928.     mov    ah,prstr
  1929.     int    dos
  1930.     mov    dx,si            ; message
  1931.     call    prtasz
  1932. popcmd2:call    poplevel        ; do the pop
  1933. popcmdx:ret
  1934. POPCMD    endp
  1935.  
  1936. ; Common Get keyword + Get Confirm sequence. Call with dx = keyword table,
  1937. ; bx = help message offset. Returns result in BX. Modifies AX, BX.
  1938. ; Returns carry clear if sucessful else carry set. Used in many places below.
  1939. keyend    proc    near
  1940.     mov    ah,cmkey
  1941.     call    comnd
  1942.     jnc    keyend1            ; nc = success
  1943.     ret                ; failure
  1944. keyend1:push    bx            ; save returned results around call
  1945.     mov    ah,cmeol        ; get c/r confirmation
  1946.     call    comnd
  1947.     pop    bx            ; recover keyword 16 bit value
  1948.     ret                ; return with carry from comnd
  1949. keyend    endp
  1950.  
  1951. srvdsa    proc    near            ; DISABLE Server commands
  1952.     mov    dx,offset srvdetab
  1953.     mov    bx,offset sdshlp
  1954.     call    keyend
  1955.     jc    srvdsa1            ; c = failure
  1956.     cmp    apctrap,0        ; disable from APC
  1957.     jne    srvdsa1            ; ne = yes
  1958.     or    denyflg,bx        ; turn on bit (deny) for that item
  1959. srvdsa1:ret
  1960. srvdsa    endp
  1961.  
  1962. srvena    proc    near            ; ENABLE Server commands
  1963.     mov    dx,offset srvdetab    ; keyword table
  1964.     mov    bx,offset sdshlp    ; help on keywords
  1965.     call    keyend
  1966.     jc    srvena1            ; c = failure
  1967.     cmp    apctrap,0        ; disable from APC
  1968.     jne    srvena1            ; ne = yes
  1969.     not    bx            ; invert bits
  1970.     and    denyflg,bx        ; turn off (enable) selected item
  1971. srvena1:ret
  1972. srvena    endp
  1973.  
  1974. ; DIAL arg list
  1975. ; Invokes macro DIAL with args or, if not present, then macro "\0IAL"
  1976. ; defined above, with args.
  1977. dial    proc    near
  1978.     mov    kstatus,kssuc        ; assume success
  1979.     mov    word ptr decbuf,4    ; length of our name
  1980.     mov    word ptr decbuf+2,'ID'    ; prefix with "DIAL "
  1981.     mov    word ptr decbuf+4,'LA'
  1982.     call    dialcom            ; look for macro "DIAL"
  1983.     jnc    dial1            ; nc = found "DIAL"
  1984.     mov    si,offset dialmac    ; default string "__DIAL"
  1985.     mov    di,offset decbuf+2    ; destination
  1986.     push    es
  1987.     mov    ax,seg decbuf
  1988.     mov    es,ax
  1989.     mov    cx,6            ; string length
  1990.     cld
  1991.     rep    movsb            ; copy string
  1992.     pop    es
  1993.     mov    word ptr decbuf,6    ; string length
  1994.     call    dialcom            ; look for it
  1995.     jc    dialx            ; c = failed, quit
  1996. dial1:    jmp    docom1            ; DO macro with bx set for domacptr
  1997.  
  1998. dialx:    mov    kstatus,kstake        ; Take file command failure
  1999.     stc                ; fail
  2000.     ret
  2001. dial    endp
  2002.  
  2003. code    ends
  2004.  
  2005. code1    segment
  2006.     assume    cs:code1
  2007.  
  2008. ; Worker for DIAL command. Find macro whose name is in offset decbuf+2
  2009. ; and whose length is in word ptr decbuf.
  2010. ; Return carry clear and macro seg in BX if success, else carry set.
  2011. dialcom    proc    far
  2012.     push    si
  2013.     push    di
  2014.     push    es
  2015.     mov    ax,ds
  2016.     mov    es,ax            ; check for existence of macro
  2017.     mov    bx,offset mcctab    ; table of macro names
  2018.     mov    cl,[bx]            ; number of names in table
  2019.     xor    ch,ch
  2020.     jcxz    dialcx            ; z = empty table, do nothing
  2021.     inc    bx            ; point to length of first name
  2022. dialc2:    mov    ax,[bx]            ; length of this name
  2023.     cmp    ax,word ptr decbuf    ; length same as desired keyword?
  2024.     jne    dialc3            ; ne = no, search again
  2025.     mov    si,bx
  2026.     add    si,2            ; point at first char of macro name
  2027.     push    cx            ; save name counter
  2028.     push    di            ; save reg
  2029.     mov    cx,word ptr decbuf    ; length of name
  2030.     mov    di,offset decbuf+2    ; point at desired macro name
  2031.     push    es            ; save reg
  2032.     push    ds
  2033.     pop    es            ; make es use data segment
  2034.     cld
  2035.     repe    cmpsb            ; match strings
  2036.     pop    es            ; need current si below
  2037.     pop    di            ; recover saved regs
  2038.     pop    cx
  2039.     jne    dialc3            ; ne = not matched
  2040.     add    bx,ax            ; length of name
  2041.     add    bx,2            ; count + name, points at word ptr
  2042.     mov    bx,[bx]            ; return word ptr in BX
  2043.     clc                ; say success
  2044.     jmp    short dialcx        ; and return
  2045.     
  2046. dialc3:    add    bx,ax            ; step to next name, add name length
  2047.     add    bx,4            ; + count and def word ptr
  2048.     loop    dialc2            ; try next name
  2049.     stc                ; say failure
  2050. dialcx:    pop    es
  2051.     pop    di
  2052.     pop    si            ; no macro
  2053.     ret
  2054. dialcom    endp
  2055. code1    ends
  2056.  
  2057. code    segment
  2058.     assume    cs:code
  2059. ; This is the SET command
  2060. ; Called analyzers return carry clear for success, else carry set.
  2061. SETCOM    PROC    NEAR            ; Dispatch all SET commands from here
  2062.     mov    kstatus,kssuc        ; global status, success
  2063.     mov    dx,offset settab    ; Parse a keyword from the set table
  2064.     mov    bx,offset sethlp
  2065.     mov    ah,cmkey
  2066.     call    comnd
  2067.     jc    setcom1            ; c = failure
  2068.     jmp    bx            ; execute analyzer routine
  2069. setcom1:ret
  2070. SETCOM    endp
  2071.  
  2072. SETATT    PROC    NEAR            ; Set attributes on | off
  2073.     mov    dx,offset atttab
  2074.     xor    bx,bx
  2075.     mov    ah,cmkey
  2076.     call    comnd
  2077.     jc    setatt3            ; c = failure
  2078.     mov    dx,bx            ; hold results in dx
  2079.     cmp    dl,0ffh            ; ON/OFF (all of them)?
  2080.     je    setatt1            ; e = yes
  2081.     push    dx
  2082.     mov    dx,offset ontab        ; get on/off state
  2083.     xor    bx,bx
  2084.     mov    ah,cmkey
  2085.     call    comnd
  2086.     pop    dx
  2087.     jc    setatt3            ; c = failure
  2088.     mov    dh,bl            ; store on/off state in dh
  2089. setatt1:push    dx
  2090.     mov    ah,cmeol
  2091.     call    comnd
  2092.     pop    dx
  2093.     jc    setatt3
  2094.     mov    al,flags.attflg        ; current flags
  2095.     not    dl            ; all but those affected
  2096.     and    al,dl            ; turn off affected flags
  2097.     or    dh,dh            ; off (dh = 0)?
  2098.     jz    setatt2            ; z = yes
  2099.     not    dl            ; affected flags back again as ones
  2100.     or    al,dl            ; turn on affected flags
  2101. setatt2:mov    flags.attflg,al
  2102. setatt3:ret
  2103. SETATT    ENDP
  2104.  
  2105. ; SET BAUD or SET SPEED
  2106. ; See system dependent routine BAUDST in file MSXxxx.ASM
  2107.  
  2108. ; SET BELL on or off
  2109.  
  2110. BELLST    PROC    NEAR
  2111.     mov    dx,offset ontab        ; on/off table
  2112.     xor    bx,bx            ; help
  2113.     call    keyend
  2114.     jc    bellst1            ; c = failure
  2115.     mov    flags.belflg,bl
  2116. bellst1:ret
  2117. BELLST    ENDP
  2118.  
  2119. ; SET BLOCK-CHECK
  2120.  
  2121. BLKSET    PROC    NEAR
  2122.     mov    dx,offset blktab    ; table
  2123.     xor    bx,bx            ; help, use table
  2124.     call    keyend
  2125.     jc    blkset1            ; c = failure
  2126.     mov    dtrans.chklen,bl    ; use this char as initial checksum
  2127. blkset1:ret
  2128. BLKSET    ENDP
  2129.  
  2130. ; SET CARRIER {ON, OFF}
  2131. setcar    proc    near
  2132.     mov    dx,offset ontab        ; table
  2133.     mov    bx,offset carhlp    ; help, use table
  2134.     call    keyend
  2135.     jc    setcar1            ; c = failure
  2136.     mov    flags.carrier,bl    ; value
  2137.     mov    cardet,0        ; clear carrier detect variable
  2138.     clc
  2139. setcar1:ret
  2140. setcar    endp
  2141.  
  2142. ; Set port addresses for COM1 .. COM4 at Kermit initialization time via
  2143. ; Environment. Called by command parser while doing Environment reading in
  2144. ; mssker.asm and via SET COM1 .. SET COM4.
  2145. COM1PORT proc    near
  2146.     mov    bx,0            ; offset of com1 port address
  2147.     jmp    short comport
  2148. COM1PORT endp
  2149. COM2PORT proc    near
  2150.     mov    bx,2            ; offset of com2 port address
  2151.     jmp    short comport
  2152. COM2PORT endp
  2153. COM3PORT proc    near
  2154.     mov    bx,4            ; offset of com3 port address
  2155.     jmp    short comport
  2156. COM3PORT endp
  2157.  
  2158. COM4PORT proc    near
  2159.     mov    bx,6            ; offset of com4 port address
  2160. ;;    jmp    comport
  2161. COM4PORT endp
  2162.  
  2163. COMPORT    proc    near            ; worker for above
  2164.     push    bx            ; save offset
  2165.     shr    bx,1            ; address bytes 0..3
  2166.     mov    ah,portfifo[bx]        ; save existing port values
  2167.     mov    al,portirq[bx]
  2168.     mov    temp2,ax        ; worker word
  2169.     mov    bx,offset rdbuf
  2170.     mov    dx,offset comhlp
  2171.     mov    ah,cmword        ; get port address number
  2172.     call    comnd
  2173.     jnc    compor3
  2174.     pop    bx            ; fail
  2175.     ret
  2176. compor3:mov    numerr,0        ; no error message
  2177.     mov    min,100h        ; smallest number
  2178.     mov    max,0fff0h        ; largest magnitude
  2179.     mov    numhlp,0        ; help
  2180.     call    numwd            ; parse this word
  2181.     jnc    compor4            ; nc = success, value in ax
  2182.     pop    bx
  2183.     ret
  2184. compor4:mov    temp1,ax        ; save port address
  2185.     mov    bx,offset rdbuf
  2186.     mov    dx,offset irqhlp
  2187.     mov    ah,cmword        ; read IRQ
  2188.     call    comnd
  2189.     jnc    compor5
  2190.     pop    bx
  2191.     ret
  2192. compor5:
  2193.     push    ax
  2194.     push    bx
  2195.     mov    ah,cmkey
  2196.     mov    bx,offset fifohlp    ; help
  2197.     mov    dx,offset FIFOtab    ; action table
  2198.     mov    comand.cmcr,1        ; null response permitted
  2199.     call    comnd
  2200.     jc    compor8            ; c = nothing present
  2201.     mov    byte ptr temp2+1,bl    ; save FIFO setting
  2202. compor8:pop    bx
  2203.     pop    ax
  2204.  
  2205.     push    ax
  2206.     mov    ah,cmeol        ; get command confirmation
  2207.     call    comnd
  2208.     pop    ax
  2209.     jnc    compor5a        ; nc = success
  2210.     ret
  2211. compor5a:or    ax,ax            ; anything given?
  2212.     jz    compor7            ; z = no
  2213.     mov    numhlp,0        ; help
  2214.     mov    numerr,0        ; no error message
  2215.     mov    min,2            ; smallest number
  2216.     mov    max,15            ; largest magnitude
  2217.     call    numwd            ; parse this word
  2218.     jnc    compor6            ; nc = success
  2219.     pop    bx
  2220.     ret
  2221. compor6:mov    byte ptr temp2,al    ; save IRQ
  2222. compor7:pop    bx            ; recover offset
  2223.     cmp    word ptr machnam,'BI'    ; check for "IBM-PC"
  2224.     jne    compor1            ; ne = not this name, fail
  2225.     cmp    word ptr machnam+2,'-M'
  2226.     jne    compor1
  2227.     cmp    word ptr machnam+4,'CP'
  2228.     jne    compor1
  2229.     push    es
  2230.     mov    al,flags.comflg        ; current comms port
  2231.     dec    al            ; count from 0, as per Bios
  2232.     shl    al,1            ; double to use word index of Bios
  2233.     cmp    al,bl            ; using this port now?
  2234.     jne    compor2            ; ne = no
  2235.     call    serrst            ; reset the port
  2236. compor2:mov    cx,40h            ; segment 40h
  2237.     mov    es,cx
  2238.     mov    ax,temp1        ; port address
  2239.     mov    es:[bx],ax        ; set port address
  2240.     pop    es
  2241.     shr    bl,1            ; coms port offset 0,2,4,6 to 0,1,2,3
  2242.     mov    ax,temp2        ; FIFO and IRQ
  2243.     mov    portirq[bx],al        ; IRQ
  2244.     mov    portfifo[bx],ah        ; FIFO
  2245.     clc
  2246. compor1:ret
  2247. COMPORT    endp
  2248.  
  2249. ; Set CONTROL PREFIXED <code>, CONTROL UNPREFIXED <code>, code can be ALL
  2250. cntlset    proc    near
  2251.     push    es
  2252.     mov    di,seg decbuf        ; copy protlist to work buffer decbuf
  2253.     mov    es,di
  2254.     mov    si,offset protlist
  2255.     mov    di,offset decbuf
  2256.     mov    cx,32
  2257.     cld
  2258.     rep    movsb
  2259.     pop    es
  2260.  
  2261.     mov    dx,offset cntltab    ; table
  2262.     mov    bx,offset cntlhlp    ; help
  2263.     mov    ah,cmkey
  2264.     call    comnd
  2265.     jc    cntlsetx        ; c = failure
  2266.     mov    rdbuf,bl        ; save operation value
  2267. cntlse1:mov    ah,cmword        ; get optional error value and msg
  2268.     mov    bx,offset rdbuf+1
  2269.     mov    dx,offset ctlhlp    ; help on numerical argument
  2270.     call    comnd
  2271.     jc    cntlsetx        ; c = failure
  2272.     mov    si,offset rdbuf+1    ; skip operational value in rdbuf
  2273.     or    ax,ax            ; anything given?
  2274.     jnz    cntlse2            ; nz = yes
  2275.     mov    ah,cmeol        ; confirm
  2276.     call    comnd
  2277.     jc    cntlsetx        ; c = failure
  2278.     push    es            ; copy work buffer decbuf to protlist
  2279.     mov    di,seg protlist
  2280.     mov    es,di
  2281.     mov    di,offset protlist
  2282.     mov    si,offset decbuf
  2283.     mov    cx,32
  2284.     cld
  2285.     rep    movsb
  2286.     pop    es
  2287.     clc
  2288.     ret
  2289.  
  2290. cntlse2:mov    al,[si]            ; look for ALL
  2291.     or    al,al            ; end of string?
  2292.     jz    cntlse1            ; z = yes, get more user input
  2293.     cmp    al,','            ; comma separator?
  2294.     jne    cntlse2a        ; ne = no
  2295.     inc    si            ; skip it
  2296.     jmp    short cntlse2
  2297. cntlse2a:or    al,20h            ; to lower
  2298.     cmp    al,'a'            ; a in ALL?
  2299.     je    cntlse8            ; e = got ALL
  2300. cntlse3:mov    domath_ptr,si
  2301.     mov    domath_cnt,16
  2302.     call    domath            ; convert to number in ax
  2303.     jc    cntlsety        ; c = failure
  2304.     mov    si,domath_ptr        ; next byte
  2305.     cmp    al,159            ; out of range?
  2306.     ja    cntlsety        ; a = yes
  2307.     cmp    al,128            ; in 8-bit range?
  2308.     jae    cntlse4            ; ae = yes
  2309.     cmp    al,31            ; out of range?
  2310.     ja    cntlsety        ; a = yes
  2311. cntlse4:mov    ah,rdbuf        ; protected/unprotected pointer 0/1
  2312.     mov    bl,al            ; char
  2313.     and    bl,not 80h        ; strip high bit from index
  2314.     xor    bh,bh
  2315.     or    ah,ah            ; protecting?
  2316.     jz    cntlse6            ; z = yes
  2317.     mov    ah,1            ; assume unprotecting 7-bit char
  2318.     and    al,80h            ; get high bit
  2319.     jz    cntlse5            ; z = no high bit
  2320.     mov    ah,80h            ; set high bit flag
  2321. cntlse5:or    decbuf[bx],ah        ; set unprotection bit
  2322.     jmp    cntlse2            ; get more input
  2323.  
  2324. cntlse6:mov    ah,1            ; assume protecting 7-bit char
  2325.     and    al,80h            ; get high bit
  2326.     jz    cntlse7            ; z = no high bit
  2327.     mov    ah,80h            ; set high bit flag
  2328. cntlse7:not    ah            ; invert bits
  2329.     and    decbuf[bx],ah        ; clear the unprotection bit
  2330.     jmp    cntlse2            ; get more input
  2331.  
  2332. cntlsetx:ret                ; success or failure
  2333.                     ; process ALL
  2334. cntlse8:mov    cx,32
  2335.     xor    bx,bx
  2336.     mov    al,rdbuf        ; get kind of operation
  2337.     or    al,al            ; prefix (0)?
  2338.     je    cntlse9            ; e = yes
  2339.     mov    al,81h            ; unprefix all (7 and 8 bit)
  2340. cntlse9:mov    decbuf[bx],al        ; set the state
  2341.     inc    bx
  2342.     loop    cntlse9            ; do all
  2343.     jmp    cntlse1            ; get more user input
  2344.  
  2345. cntlsety:mov    ah,cmeol        ; confirm
  2346.     call    comnd
  2347.     mov    ah,prstr
  2348.     mov    dx,offset badcntlmsg    ; say out of range
  2349.     int    dos
  2350.     stc
  2351.     ret
  2352. cntlset    endp
  2353.  
  2354. ; SET COUNTER number    for script IF COUNTER number <command>
  2355. TAKECTR    PROC    NEAR
  2356.     mov    min,0            ; get decimal char code
  2357.     mov    max,65535        ; range is 0 to 65535 decimal
  2358.     mov    numhlp,offset takchlp    ; help message
  2359.     mov    numerr,0        ; error message
  2360.     call    num0            ; convert number, return it in ax
  2361.     jc    takect2            ; c = error
  2362.     push    ax            ; save numerical code
  2363.     mov    ah,cmeol
  2364.     call    comnd            ; get a confirm
  2365.     pop    ax            ; recover ax
  2366.     jc    takect2            ; c = failure
  2367.     cmp    taklev,0        ; in a Take file?
  2368.     je    takect4            ; e = no
  2369.     push    bx
  2370.     mov    bx,takadr
  2371.     mov    [bx].takctr,ax        ; set COUNT value
  2372.     pop    bx
  2373.     clc                ; success
  2374. takect2:ret
  2375. takect4:mov    dx,offset takcerr    ; say must be in Take file
  2376.     jmp    reterr            ; display msg and return carry clear
  2377. TAKECTR    ENDP
  2378.  
  2379. ; RESET 
  2380. reset    proc    near
  2381.     mov    dx,offset resettab
  2382.     xor    bx,bx
  2383.     call    keyend
  2384.     jnc    reset1            ; nc = success
  2385.     ret                ; failure
  2386. reset1:    mov    al,bl            ; reset clock
  2387.     mov    bx,portval
  2388.     mov    starttime[bx+3],bl    ; remember in high byte
  2389.     ret
  2390. reset    endp
  2391.  
  2392. ; SET DEBUG {OFF | ON | SESSSION | PACKETS}
  2393.  
  2394. DEBST    PROC       NEAR
  2395.     mov    dx,offset debtab
  2396.     mov    bx,offset debhlp
  2397.     call    keyend
  2398.     jnc    debst1            ; nc = success
  2399.     ret                ; failure
  2400. debst1:    or    flags.debug,bl        ; set the mode, except for Off
  2401.     or    bx,bx            ; OFF?
  2402.     jnz    debst2            ; nz = no
  2403.     mov    flags.debug,bl        ; set the DEBUG flags off
  2404. debst2:    clc                ; success
  2405.     ret
  2406. DEBST    ENDP
  2407.  
  2408. ; SET DESTINATION   of incoming files
  2409.  
  2410. DESSET    PROC    NEAR
  2411.     mov    dx,offset destab
  2412.     xor    bx,bx
  2413.     call    keyend
  2414.     jc    desset1            ; c = failure
  2415.     mov    flags.destflg,bl    ; set the destination flag
  2416. desset1:ret
  2417. DESSET    ENDP
  2418.  
  2419. ; SET DEFAULT-DISK    for sending/receiving, etc
  2420. ; See cwdir in file mssker
  2421.  
  2422. ; SET DELAY seconds   Used only for SEND command in local mode
  2423. SETDELY    PROC    NEAR
  2424.     mov    min,0            ; smallest acceptable value
  2425.     mov    max,63            ; largest acceptable value
  2426.     mov    numhlp,offset delyhlp    ; help message
  2427.     mov    numerr,0        ; complaint message
  2428.     call    num0            ; parse numerical input
  2429.     jc    setdly1            ; c = error
  2430.     mov    trans.sdelay,al
  2431. setdly1:ret                ; success or failure
  2432. SETDELY    ENDP
  2433.  
  2434. ; SET DISPLAY Quiet/Regular/Serial/7-Bit/8-Bit (inverse of Set Remote on/off)
  2435. ; Accepts two keywords in one command
  2436. disply    proc    near
  2437.     mov    ah,cmkey
  2438.     mov    dx,offset distab
  2439.     mov    bx,offset dishlp
  2440.     call    comnd
  2441.     jnc    displ0            ; nc = success
  2442.     ret                ; return failure
  2443. displ0:    mov    temp1,bx        ; save parsed value
  2444.     mov    temp2,0ffffh        ; assume no second keyword
  2445.     mov    comand.cmcr,1        ; bare CR's are allowed
  2446.     mov    ah,cmkey        ; parse for second keyword
  2447.     mov    dx,offset distab
  2448.     mov    bx,offset dishlp
  2449.     call    comnd
  2450.     jc    displ1            ; no keyword
  2451.     mov    temp2,bx        ; get key value
  2452. displ1:    mov    comand.cmcr,0        ; bare CR's are not allowed
  2453.     mov    ah,cmeol
  2454.     call    comnd            ; confirm
  2455.     jnc    displ2            ; nc = success
  2456.     ret                ; failure
  2457. displ2:    mov    ax,temp1        ; examine first key value
  2458.     call    dispcom            ; do common code
  2459.     mov    ax,temp2        ; examine second key value
  2460.  
  2461. dispcom:or    ax,ax            ; check range
  2462.     jle    dispc3            ; le = not legal, ignore
  2463.     cmp    al,7            ; 7-8 bit value?
  2464.     jge    dispc2            ; ge = yes
  2465.     and    flags.remflg,not(dquiet+dregular+dserial)
  2466.     or    flags.remflg,al        ; set display mode
  2467.     clc                ; success
  2468.     ret                ; check next key value
  2469. dispc2:    cmp    al,8            ; set 8-bit wide display?
  2470.     ja    dispc3            ; a = bad value
  2471.     and    flags.remflg,not d8bit    ; assume want 7 bit mode
  2472.     cmp    al,7            ; really want 7 bit mode?
  2473.     je    dispc3            ; e = yes
  2474.     or    flags.remflg,d8bit    ; set 8 bit flag
  2475. dispc3:    clc                ; success
  2476.     ret                ; end of display common code
  2477. disply    endp
  2478.  
  2479.  
  2480. ; Set Dump filename  for saving screen images on disk.
  2481. ; Puts filename in global string dmpname
  2482. setdmp    proc    near
  2483.     mov    bx,offset rdbuf        ; work area
  2484.     mov     dx,offset dmphlp    ; help message
  2485.     mov    ah,cmword        ; allow paths
  2486.     call    comnd
  2487.     jc    setdmp2            ; c = failure
  2488.     mov    ah,cmeol
  2489.     call    comnd
  2490.     jc    setdmp2            ; c = failure
  2491.     mov    dx,offset rdbuf        ; assume we will use this text
  2492.     call    strlen            ; filename given?
  2493.     mov    si,dx            ; for strcpy
  2494.     or    cx,cx            ; length of user's filename
  2495.     jg    setdmp1            ; g = filename is given
  2496.     mov    si,offset dmpdefnam    ; no name, use default instead
  2497. setdmp1:mov    di,offset dmpname    ; copy to globally available loc
  2498.     call    strcpy
  2499.     clc
  2500. setdmp2:ret
  2501. setdmp    endp
  2502.  
  2503. ; Set DUPLEX {FULL, HALF}
  2504. setdup    proc    near
  2505.     xor    bx,bx
  2506.     mov    dx,offset duptab
  2507.     call    keyend
  2508.     jc    setdup1            ; c = failure
  2509.     mov    si,portval
  2510.     mov    [si].duplex,bl        ; set value
  2511.     mov    [si].ecoflg,0        ; turn off local echoing
  2512.     or    bl,bl            ; full duplex?
  2513.     jz    setdup1            ; z = yes
  2514.     mov    [si].floflg,0        ; no flow control for half duplex
  2515.     mov    [si].ecoflg,1        ; turn on local echoing
  2516.     call    serrst            ; reset port so opening uses above
  2517. setdup1:ret
  2518. setdup    endp
  2519.  
  2520. ; SET EOF
  2521.  
  2522. SETEOF    PROC    NEAR
  2523.     xor    bx,bx
  2524.     mov    dx,offset seoftab
  2525.     call    keyend
  2526.     jc    seteof1            ; c = failure
  2527.     mov    flags.eofcz,bl        ; set value
  2528. seteof1:ret
  2529. SETEOF    ENDP
  2530.  
  2531. ; SET End-of-Packet char (for Sent packets)
  2532. ; Archic, here for downward compatibility
  2533. EOLSET    PROC    NEAR
  2534.     mov    stflg,'S'        ; set send/receive flag to Send
  2535.     jmp    sreol            ; use Set Send/Rec routine do the work
  2536. EOLSET    ENDP
  2537.  
  2538. ; SET ERRORLEVEL number
  2539. SETERL    PROC    NEAR
  2540.     mov    numhlp,offset erlhlp    ; help
  2541.     mov    numerr,0        ; error message
  2542.     mov    min,0            ; smallest number
  2543.     mov    max,255            ; largest magnitude
  2544.     call    num0            ; parse numerical input
  2545.     jc    seterl1            ; c = error
  2546.     mov    errlev,al        ; store result
  2547.     clc
  2548. seterl1:ret
  2549. SETERL    ENDP
  2550.  
  2551. ; SET ESCAPE character.
  2552. ; Accept literal control codes and \### numbers. [jrd] 18 Oct 1987
  2553. ESCSET    PROC    NEAR
  2554.     mov    ah,cmword
  2555.     mov    bx,offset rdbuf        ; work space
  2556.     mov    dx,offset eschlp    ; help
  2557.     call    comnd
  2558.     jc    escse2            ; c = failure
  2559.     or    ax,ax            ; anything given?
  2560.     jnz    escse1            ; nz = yes
  2561.     mov    dx,offset ermes6    ; more parameters needed
  2562.     jmp    reterr
  2563. escse1:    push    ax            ; save string length
  2564.     mov    ah,cmeol        ; get a confirm
  2565.     call    comnd
  2566.     pop    ax
  2567.     jc    escse2            ; c = failure
  2568.     mov    domath_ptr,offset rdbuf
  2569.     mov    domath_cnt,ax
  2570.     call    domath            ; convert to number in ax
  2571.     cmp    ax,spc            ; is it a control code?
  2572.     jae    escse3            ; ae = no, complain
  2573.     or    ax,ax            ; non-zero too?
  2574.     jz    escse3            ; z = zero
  2575.     mov    trans.escchr,al        ; save new escape char code
  2576.     clc
  2577. escse2:    ret
  2578. escse3:    mov    dx,offset escerr
  2579.     jmp    reterr
  2580. ESCSET    ENDP
  2581.  
  2582. ; Set EXIT 
  2583. ; SET WARNING {ON, OFF}
  2584. setexitwarn proc near
  2585.     mov    dx,offset exittab    ; exit table
  2586.     xor    bx,bx
  2587.     mov    ah,cmkey
  2588.     call    comnd
  2589.     jc    setexit1
  2590.     or    bl,bl            ; warning?
  2591.     jnz    setexit1        ; nz = no
  2592.     mov    bx,offset exitwhlp    ; warning help
  2593.     mov    dx,offset ontab
  2594.     call    keyend
  2595.     jc    setexit1        ; c = failure
  2596.     mov    flags.exitwarn,bl    ; set value
  2597. setexit1:ret
  2598. setexitwarn endp
  2599.  
  2600. ; SET FILE {DISPLAY, WARNING, TYPE, CHARACTER-SET}
  2601. SETFILE    proc    near
  2602.     mov    dx,offset setfitab    ; SET FILE table
  2603.     xor    bx,bx
  2604.     mov    ah,cmkey
  2605.     call    comnd
  2606.     jc    setfiy            ; c = failure
  2607.     or    bl,bl            ; Warning?
  2608.     jnz    setfi1            ; nz = no
  2609.                     ; entry point for old SET WARNING
  2610. FILWAR:    mov    dx,offset warntab    ; warning table, on, off, no-super
  2611.     xor    bx,bx
  2612.     call    keyend
  2613.     jc    setfiy            ; c = failure
  2614.     mov    flags.flwflg,bl        ; set the filewarning flag
  2615. setfiy:    ret
  2616.  
  2617. setfi1:    cmp    bl,1            ; SET FILE CHARACTER-SET?
  2618.     jne    setfi2            ; ne = no
  2619.     mov    dx,offset setchtab    ; table of char sets
  2620.     xor    bx,bx
  2621.     call    keyend            ; get the set id
  2622.     jc    setfiy            ; c = error
  2623.     mov    flags.chrset,bx        ; save the id
  2624.     cmp    bx,866            ; setting CP866?
  2625.     jne    setfi1a            ; ne = no
  2626.     cmp    dtrans.xchset,xfr_cyrillic ; using TRANSFER of Cryillic?
  2627.     je    setfi1a            ; e = yes
  2628.     mov    dtrans.xchset,xfr_cyrillic ; force TRANSFER of Cyrillic
  2629.     mov    trans.xchset,xfr_cyrillic
  2630.     mov    ah,prstr
  2631.     mov    dx,offset setchmsg    ; show warning
  2632.     int    dos
  2633.     clc
  2634.     ret
  2635. setfi1a:cmp    bx,932            ; setting Shift-JIS?
  2636.     jne    setfi1b            ; ne = no
  2637.     mov    dtrans.xchset,xfr_japanese ; force TRANSFER of Japanese-EUC
  2638.     mov    trans.xchset,xfr_japanese
  2639.     mov    ah,prstr
  2640.     mov    dx,offset setchmsg2    ; show warning
  2641.     int    dos
  2642.     clc
  2643.     ret
  2644. setfi1b:cmp    bx,862            ; setting CP862?
  2645.     jne    setfi1c            ; ne = no
  2646.     mov    dtrans.xchset,xfr_hebiso ; force TRANSFER of Latin-Hebrew
  2647.     mov    trans.xchset,xfr_hebiso
  2648.     mov    ah,prstr
  2649.     mov    dx,offset setchmsg3    ; show warning
  2650.     int    dos
  2651. setfi1c:clc
  2652.     ret
  2653.  
  2654. setfi2:    cmp    bl,2            ; SET FILE TYPE?
  2655.     jne    setfi3            ; ne = 3
  2656.     mov    dx,offset xftyptab    ; table of types
  2657.     xor    bx,bx
  2658.     call    keyend
  2659.     jc    setfix            ; c = error
  2660.     mov    dtrans.xtype,bl        ; store transfer type
  2661.     mov    trans.xtype,bl        ; store transfer type
  2662.     ret
  2663. setfi3:    cmp    bl,3            ; SET FILE DISPLAY?
  2664.     jne    setfi4            ; ne = no
  2665.     mov    dx,offset distab2    ; table
  2666.     xor    bx,bx
  2667.     call    keyend
  2668.     jc    setfix            ; c = failure
  2669.     and    flags.remflg,not(dquiet+dregular+dserial)
  2670.     or    flags.remflg,bl        ; set display mode
  2671.     clc
  2672. setfix:    ret
  2673. setfi4:    cmp    bl,4            ; SET FILE INCOMPLETE?
  2674.     jne    setfix            ; ne = no
  2675.                     ; SET INCOMPLETE file disposition
  2676. ABFSET:    mov    dx,offset abftab
  2677.     xor    bx,bx
  2678.     call    keyend
  2679.     jc    abfset1            ; c = failure
  2680.     mov    flags.abfflg,bl        ; Set the aborted file flag
  2681. abfset1:ret
  2682. SETFILE    endp
  2683.  
  2684. ; SET FLOW-CONTROL {NONE, XONXOFF, RTS/CTS}
  2685.  
  2686. FLOSET    PROC    NEAR
  2687.     mov    dx,offset flotab
  2688.       xor    bx,bx
  2689.     call    keyend
  2690.     jc    floset3            ; c = failure
  2691.     mov    si,portval
  2692.     mov    ax,floxon        ; xon/xoff pair
  2693.     or    bx,bx            ; any flow control?
  2694.     jz    floset1            ; z = none
  2695.     test    bx,1+2            ; using xon/xoff?
  2696.     jnz    floset2            ; nz = xon/xoff
  2697.     cmp    flags.comflg,'F'
  2698.     je    floset1
  2699.     cmp    flags.comflg,4        ; UART? (RTS/CTS case)
  2700.     ja    floset4            ; a = no, error
  2701. floset1:xor    ax,ax            ; clear chars for RTS/CTS and none
  2702. floset2:mov    [si].flowc,ax        ; flow control values
  2703.     mov    [si].floflg,bl        ; flow control kind
  2704.     clc
  2705. floset3:ret
  2706. floset4:mov    dx,offset ermes7    ; error message
  2707.     jmp    reterr
  2708. FLOSET    ENDP
  2709.  
  2710. ; SET FOSSIL CLOSE-ON-DONE
  2711. FOSSET    proc    near
  2712.     mov    dx,offset fossiltab
  2713.     xor    bx,bx
  2714.     mov    ah,cmkey
  2715.     call    comnd
  2716.     jc    fossetx            ; c = failure
  2717.     mov    dx,offset ontab        ; get on/off state
  2718.     mov    bx,offset fossilhlp
  2719.     mov    ah,cmkey
  2720.     call    comnd
  2721.     jnc    fosset1
  2722.     ret                ; c = failure
  2723.  
  2724. fosset1:push    bx
  2725.     mov    ah,cmeol
  2726.     call    comnd
  2727.     pop    bx
  2728.     jc    fossetx            ; failure
  2729.     mov    fossilflag,bl        ; set flag
  2730.     clc
  2731. fossetx:ret
  2732. FOSSET    endp
  2733.  
  2734. ; SET HANDSHAKE
  2735. ; Add ability to accept general decimal code.
  2736. HNDSET    PROC    NEAR
  2737.     mov    dx,offset hndtab    ; table to scan
  2738.     mov    bx,offset hnd1hlp    ; help message
  2739.     mov    ah,cmkey
  2740.     call    comnd
  2741.     jc    hnd2            ; c = failure
  2742.     cmp    bl,0ffh            ; want a general char code?
  2743.     jne    hnd1            ; ne = no
  2744.     mov    min,0            ; get decimal char code
  2745.     mov    max,255            ; range is 0 to 255 decimal
  2746.     mov    numhlp,offset erlhlp    ; help msg
  2747.     mov    numerr,0        ; error message
  2748.     call    num0            ; convert number, return it in ax
  2749.     jc    hnd2            ; c = error
  2750.     mov    bx,ax            ; recover numerical code
  2751. hnd1:    push    bx            ; handshake type
  2752.     mov    ah,cmeol
  2753.     call    comnd            ; get a confirm
  2754.     pop    bx            ; recover bx
  2755.     jc    hnd2            ; c = failure
  2756.     mov    si,portval
  2757.     or    bl,bl            ; setting handshake off?
  2758.     jz    hnd0            ; z = yes
  2759.     mov    [si].hndflg,1        ; turn on handshaking
  2760.     mov    [si].hands,bl        ; use this char as the handshake
  2761.     clc                ; success
  2762.     ret
  2763. hnd0:    mov    [si].hndflg,bl        ; no handshaking
  2764.     clc                ; success
  2765. hnd2:    ret
  2766. HNDSET    ENDP
  2767.  
  2768. ;
  2769. ; Set Input commands (default-timeout, timeout-action, case, echo)
  2770. ; By Jim Strudevant [jrs]
  2771. INPSET    PROC    NEAR
  2772.     mov    ah,cmkey        ; key word
  2773.     mov    dx,offset inptab    ; from inputtable
  2774.     xor    bx,bx            ; no hints
  2775.     call    comnd            ; get the word
  2776.     jc    inpset1            ; c = failure
  2777.     jmp    bx            ; do the sub command
  2778. inpset1:ret
  2779. ;
  2780. ; Set Input Default-timeout in seconds
  2781. ;
  2782. inptmo:    mov    numhlp,offset intoms    ; help
  2783.     mov    numerr,0        ; error message
  2784.     mov    min,0            ; smallest number
  2785.     mov    max,-1            ; largest magnitude
  2786.     call    num0            ; parse numerical input
  2787.     jc    inptmo1            ; c = error
  2788.     mov    script.indfto,ax    ; store result
  2789. inptmo1:ret
  2790. ;
  2791. ; Set Input Timeout action (proceed or quit)
  2792. ;
  2793. inpact:    mov    dx,offset inactb    ; from this list
  2794.     xor    bx,bx            ; no hints
  2795.     call    keyend            ; get it
  2796.     jc    inpact1            ; c = failure
  2797.     mov    script.inactv,bl    ; save the action
  2798. inpact1:ret
  2799. ;
  2800. ; Set Input Echo on or off
  2801. ;
  2802. inpeco:    mov    dx,offset ontab        ; from this list
  2803.     xor    bx,bx            ; no hints
  2804.     call    keyend            ; get it
  2805.     jc    inpeco1            ; c = failure
  2806.     mov    script.inecho,bl    ; save the action
  2807. inpeco1:ret
  2808. ;
  2809. ; Set Input Case observe or ignore
  2810. ;
  2811. inpcas:    mov    dx,offset incstb    ; from this list
  2812.     xor    bx,bx            ; no hints
  2813.     call    keyend            ; get it
  2814.     jc    inpcas1            ; c = failure
  2815.     mov    script.incasv,bl    ; save the action
  2816. inpcas1:ret
  2817.  
  2818. infilt:    mov    dx,offset ontab        ; filter input, table
  2819.     xor    bx,bx
  2820.     call    keyend
  2821.     jc    infilt1
  2822.     mov    script.infilter,bl
  2823. infilt1:ret
  2824. INPSET    ENDP
  2825.  
  2826. ; Set length of script buffer for INPUT/REINPUT at Kermit initialization
  2827. ; time via Environment. Called by command parser while doing Environment
  2828. ; reading in mssker.asm. Do not call after Kermit has initialized.
  2829. SETINPBUF proc    near
  2830.     mov    scpbuflen,128        ; store default buffer length
  2831.     mov    numhlp,0        ; no help
  2832.     mov    numerr,0        ; no error message
  2833.     mov    min,2            ; smallest number (must be non-zero)
  2834.     mov    max,65535        ; largest magnitude (16 bits worth)
  2835.     call    num0            ; parse numerical input
  2836.     jc    setinpbx        ; c = error
  2837.     mov    scpbuflen,ax        ; store result
  2838.     clc
  2839. setinpbx:ret
  2840. SETINPBUF endp
  2841.  
  2842. ; SET KEY
  2843. ; Jumps to new Set Key routine
  2844. setkey    proc    near        
  2845.     cmp    stkadr,0    ; keyboard translator present?
  2846.     je    setk4        ; e = no, use this routine
  2847.     mov    bx,stkadr    ; yes, get offset of procedure
  2848.     jmp    bx        ; jump to keyboard translator
  2849. setk4:    mov    dx,offset ermes5
  2850.     jmp    reterr        ; else print error message
  2851. setkey    endp
  2852.  
  2853. ; SET LOCAL-ECHO {ON | OFF}
  2854.  
  2855. LCAL    PROC    NEAR
  2856.     mov    dx,offset ontab
  2857.     xor    bx,bx
  2858.     call    keyend
  2859.     jc    lcal1            ; c = failure
  2860.     mov    si,portval
  2861.     mov    [si].ecoflg,bl        ; Set the local echo flag
  2862. lcal1:    ret
  2863. LCAL    ENDP
  2864.  
  2865. ; LOG  {PACKETS | SESSION | TRANSACTION} filename
  2866.  
  2867. setcpt    proc    near
  2868.     mov    dx,offset logtab    ; kinds of logging
  2869.     mov    bx,offset loghlp    ; help on kind of logging
  2870.     mov    ah,cmkey        ; parse keyword
  2871.     call    comnd
  2872.     jnc    setcp20            ; nc = success
  2873.     ret                ; failure
  2874. setcp20:mov    numhlp,bx        ; save the parsed value
  2875.     mov    bx,offset rdbuf        ; holds the complete filename
  2876.     mov     dx,offset filhlp    ; ask for filename
  2877.     mov    ah,cmword        ; allow paths
  2878.     call    comnd
  2879.     jnc    setcp21            ; nc = success
  2880.     ret                ; failure
  2881. setcp21:mov    bx,offset rdbuf+100    ; optional APPEND or NEW keyword
  2882.     mov     dx,offset loghlp2    ; help with trailer keywords
  2883.     mov    ah,cmword        ; allow paths
  2884.     call    comnd
  2885.     jnc    setcp21a        ; nc = success
  2886.     ret                ; failure
  2887. setcp21a:mov    ah,cmeol
  2888.     call    comnd            ; get a confirm
  2889.     jnc    setcp22            ; nc = success
  2890.     ret                ; failure
  2891. setcp22:mov    bx,numhlp        ; recover kind of logging
  2892.     mov    dx,offset rdbuf        ; length of filename to cx
  2893.     call    strlen            ; length of given filename
  2894.     test    bl,logpkt        ; packet logging?
  2895.     jz    setcp2            ; z = no, try others
  2896.     mov    dx,offset lpktnam    ; filename
  2897.     jcxz    setcp1            ; z = no filename given
  2898.     mov    si,offset rdbuf        ; get new name
  2899.     mov    di,dx            ; destination
  2900.     call    strcpy            ; replace old name
  2901. setcp1:    cmp    ploghnd,-1        ; packet log file already open?
  2902.     je    setcp6            ; e = no, open it
  2903.     jmp    setcp16            ; say file is open already
  2904.  
  2905. setcp2:    test    bl,logses        ; session logging?
  2906.     jz    setcp4            ; z = no, try others
  2907.     mov    dx,offset lsesnam    ; use default name
  2908.     jcxz    setcp3            ; z = no filename given
  2909.     mov    si,offset rdbuf        ; get new name
  2910.     mov    di,dx            ; destination
  2911.     call    strcpy            ; replace old name
  2912. setcp3:    cmp    sloghnd,-1        ; transaction file already open?
  2913.     je    setcp6            ; e = no, open it
  2914.     jmp    setcp16            ; say file is open already
  2915.  
  2916. setcp4:    test    bl,logtrn        ; transaction logging?
  2917.     jz    setcp14            ; z = no, error
  2918.     mov    dx,offset ltranam    ; use default name
  2919.     jcxz    setcp5            ; z = no filename given
  2920.     mov    si,offset rdbuf        ; get new name
  2921.     mov    di,dx            ; destination
  2922.     call    strcpy            ; replace old name
  2923. setcp5:    cmp    tloghnd,-1        ; transaction file already open?
  2924.     je    setcp6            ; e = no, open it
  2925.     jmp    setcp16            ; say file is open already
  2926.  
  2927. setcp6:    mov    ax,dx            ; place for filename for isfile
  2928.     call    isfile            ; does file exist already?
  2929.     jc    setcp7            ; c = does not exist so use create
  2930.     test    byte ptr filtst.dta+21,1fh ; file attributes, ok to write?
  2931.     jnz    setcp14            ; nz = no, use error exit    
  2932.     mov    ah,open2        ; open existing file
  2933.     mov    al,1+1+20h        ;  for writing and reading, deny write
  2934.     int    dos
  2935.     jc    setcp14            ; if carry then error
  2936.     mov    bx,ax            ; file handle for seeking
  2937.     xor    cx,cx            ; high order displacement
  2938.     xor    dx,dx            ; low order part of displacement
  2939.     mov    ah,lseek        ; seek to EOF (to do appending)
  2940.     mov    al,2            ; says to EOF
  2941.     int    dos
  2942.     mov    di,word ptr rdbuf+100    ; trailing arg, get two letters
  2943.     and    di,not 2020h        ; to upper case
  2944.     cmp    di,'EN'            ; NEW?
  2945.     jne    setcp8            ; ne = no
  2946.     mov    dx,offset rdbuf        ; filename
  2947.     mov    ah,del2            ; delete to create new file below
  2948.     int    dos
  2949.  
  2950. setcp7:    test    filtst.fstat,80h    ; access problem?
  2951.     jnz    setcp14            ; nz = yes, stop here
  2952.     mov    ah,creat2        ; function is create
  2953.     mov    cx,20H            ; turn on archive bit
  2954.     int    dos            ; create the file, DOS 2.0
  2955.     jc    setcp14            ; if carry bit set then error
  2956.     mov    bx,ax            ; file handle
  2957.  
  2958. setcp8:    cmp    numhlp,logpkt        ; packet logging?
  2959.     jne    setcp9            ; ne = no
  2960.     mov    ploghnd,bx        ; save transaction log handle here
  2961.     jmp    short setcp12
  2962. setcp9:    cmp    numhlp,logses        ; session logging?
  2963.     jne    setcp10            ; ne = no
  2964.     mov    sloghnd,bx        ; save session log handle here
  2965.     jmp    short setcp12
  2966. setcp10:mov    tloghnd,bx        ; save transaction log handle here
  2967.  
  2968. setcp12:mov    ax,numhlp        ; kind of Logging
  2969.     or    flags.capflg,al        ; accumulate kinds of logging
  2970.     clc                ; success
  2971.     ret
  2972.  
  2973. setcp14:mov    dx,offset errcap    ; give error message
  2974.     jmp    reterr            ; and display it
  2975.  
  2976. setcp16:mov    ah,prstr        ; file already open
  2977.     mov    dx,offset erropn
  2978.     int    dos
  2979.     clc                ; return success
  2980.     ret
  2981. setcpt    endp
  2982.  
  2983. ; SET MODE LINE
  2984.  
  2985. MODL    PROC    NEAR
  2986.     mov    dx,offset ontab        ; parse an on or off
  2987.     xor    bx,bx            ; no special help
  2988.     call    keyend
  2989.     jc    modl1            ; c = failure
  2990.     mov    flags.modflg,bl        ; set flag appropriately
  2991. modl1:    ret
  2992. MODL    ENDP
  2993.  
  2994. ; SET OUTPUT commands
  2995. setoutput proc    near
  2996.     mov    dx,offset outputtab    ; OUTPUT command table
  2997.     xor    bx,bx            ; no special help
  2998.     mov    ah,cmkey
  2999.     call    comnd
  3000.     jc    setout1            ; c = failure
  3001.     jmp    short setopace
  3002. setout1:ret    
  3003. setoutput endp
  3004.  
  3005. ; Set OUTPUT Pacing <number millisec between chars>
  3006. setopace proc    near
  3007.     mov    numhlp,offset opacehlp    ; help
  3008.     mov    numerr,0        ; no error message
  3009.     mov    min,0            ; smallest number
  3010.     mov    max,65535        ; largest magnitude (16 bits worth)
  3011.     call    num0            ; parse numerical input
  3012.     jc    setopac1        ; c = error
  3013.     mov    outpace,ax        ; store result
  3014.     clc
  3015. setopac1:ret
  3016. setopace endp
  3017.  
  3018. ; Set Macro Error
  3019. setmacerr proc    near
  3020.     mov    dx,offset macrotab    ; keyword
  3021.     xor    bx,bx
  3022.     mov    ah,cmkey
  3023.     call    comnd
  3024.     jnc    setmacer1
  3025.     ret                ; failure
  3026. setmacer1:
  3027.     push    bx            ; save first keyword ident
  3028.     mov    dx,offset ontab        ; on/off table
  3029.     xor    bx,bx
  3030.     call    keyend
  3031.     pop    ax            ; first keyword ident
  3032.     jnc    setmacer2        ; nc = success
  3033.     ret
  3034. setmacer2:or    al,al            ; "error" (0)?
  3035.     jz    setmacer3        ; z = yes
  3036.     mov    macroerror,bl        ; set error action flag
  3037. setmacer3:clc
  3038.     ret
  3039. setmacerr endp
  3040.  
  3041. ; SET MODEM text    creates macro named _MODEM
  3042. setmodem proc    near
  3043.     mov    word ptr rdbuf+2,'m_'    ; macro name "_modem"
  3044.     mov    word ptr rdbuf+4,'do'
  3045.     mov    word ptr rdbuf+6,'me'
  3046.     mov    rdbuf+8,' '        ; separator
  3047.     mov    bx,offset rdbuf+9
  3048.     mov    ax,length rdbuf-9    ; usable length of rdbuf
  3049.     add    ax,offset rdbuf        ; ax = amount of buffer used
  3050.     mov    comand.cmblen,ax    ; our new buffer length
  3051.     mov    comand.cmdonum,1    ; \number conversion allowed
  3052.     mov    ah,cmline        ; get a line of text
  3053.     mov    dx,offset askhlp3    ; help, bx is buffer offset
  3054.     push    bx            ; save starting offset
  3055.     call    comnd            ; get macro definition text
  3056.     pop    bx
  3057.     jnc    setmod1            ; nc = success
  3058.     ret                ; failure
  3059. setmod1:mov    cx,bx
  3060.     sub    cx,offset rdbuf+2    ; length of command line
  3061.     jmp    dodecom
  3062. setmodem endp
  3063.  
  3064. ; SET PARITY
  3065.  
  3066. SETPAR    PROC    NEAR
  3067.     mov    dx,offset partab    ; parity table
  3068.     xor    bx,bx
  3069.     mov    ah,cmkey
  3070.     call    comnd
  3071.     jnc    setp1            ; nc = success
  3072.     ret
  3073. setp1:    mov    si,portval        ; port structure
  3074.     mov    bh,[si].parflg        ; current parity setting
  3075.     or    bh,bl            ; merge hardware parity bits
  3076.     mov    byte ptr temp,bh    ; save results around calls
  3077.     test    bl,PARHARDWARE        ; using hardware parity?
  3078.     jz    setpt3            ; z = no
  3079.     mov    dx,offset parhwtab    ; hardware parity table
  3080.     xor    bx,bx
  3081.     mov    ah,cmkey
  3082.     call    comnd
  3083.     jnc    setpt2
  3084.     ret
  3085. setpt2:    cmp    flags.comflg,'4'    ; physical serial port?
  3086.     jbe    setpt3            ; be = yes
  3087.     mov    dx,offset ermes8    ; say can't use Hardware on non-UART
  3088.     jmp    reterr
  3089.  
  3090. setpt3:    mov    ah,cmeol
  3091.     push    bx
  3092.     call    comnd
  3093.     pop    bx
  3094.     jnc    setpt4
  3095.     ret
  3096. setpt4:    mov    si,portval        ; port structure
  3097.     mov    [si].parflg,bl        ; store the parity flag
  3098.     test    byte ptr temp,PARHARDWARE ; used hardware before or now?
  3099.     jz    setpt5            ; z = no
  3100.     call    serrst            ; reset port for hardware reinit
  3101. setpt5:    clc
  3102.     ret
  3103. SETPAR    ENDP
  3104.  
  3105. ; Set Print filename  for writing material to printers.
  3106. ; Puts filename in global string prnname
  3107. setprn    proc    near
  3108.     mov    bx,offset rdbuf        ; work area
  3109.     mov     dx,offset prnhlp    ; help message
  3110.     mov    ah,cmword        ; allow paths
  3111.     call    comnd
  3112.     jc    setprn3            ; c = failure
  3113.     mov    ah,cmeol
  3114.     call    comnd
  3115.     jc    setprn3            ; c = failure
  3116.     mov    dx,offset rdbuf        ; assume we will use this text
  3117.     call    strlen            ; filename given?
  3118.     mov    si,dx            ; for strcpy
  3119.     or    cx,cx            ; length of user's filename
  3120.     jg    setprn1            ; g = filename is given
  3121.     mov    si,offset prndefnam    ; no name, use default instead
  3122. setprn1:mov    di,offset prnname    ; copy to globally available loc
  3123.     call    strcpy
  3124.     cmp    prnhand,0        ; handle already in use?
  3125.     jle    setprn2            ; le = no
  3126.     call    pntflsh            ; flush current buffer
  3127.     mov    bx,prnhand        ; close the file now
  3128.     cmp    bx,4            ; don't close DOS PRN
  3129.     je    setprn2            ; e = already available
  3130.     mov    ah,close2
  3131.     int    dos
  3132. setprn2:call    prnopen            ; open printer now, may set carry
  3133.     jnc    setprn3            ; nc = success
  3134.     mov    ah,prstr
  3135.     push    ds
  3136.     mov    dx,seg prnerr
  3137.     mov    ds,dx
  3138.     mov    dx,offset prnerr    ; say can't open the file
  3139.     int    dos
  3140.     pop    ds
  3141.     mov    si,offset prndefnam    ; use default name as fallback
  3142.     mov    di,offset prnname    ; copy to globally available loc
  3143.     call    strcpy
  3144.     mov    prnhand,4        ; declare handle to be DOS PRN
  3145. setprn3:ret
  3146. setprn    endp
  3147.  
  3148. ; SET PROMPT  Allow user to change the "Kermit-MS>" prompt
  3149. ; {string} and \fchar(number) notation permitted to represent special chars.
  3150. ; String will be made asciiz
  3151.  
  3152. PROMSET    PROC    NEAR
  3153.     mov    ah,cmline
  3154.     mov    bx,offset rdbuf        ; read the prompt string
  3155.     mov    dx,offset prmmsg
  3156.     mov    comand.cmblen,length promptbuf -1 ; buffer length
  3157.     mov    comand.cmper,1        ; do not allow variable substitutions
  3158.     call    comnd
  3159.     jc    prom2            ; c = failure
  3160.     or    ax,ax            ; prompt string?
  3161.     jnz    prom0            ; nz = yes
  3162.     mov    ax,offset kerm        ; no, restore default prompt
  3163.     jmp    short prom1
  3164. prom0:    mov    si,offset rdbuf        ; source = new prompt string
  3165.     mov    di,offset promptbuf    ; destination
  3166.     call    strcpy            ; copy string to final buffer
  3167.     mov    bx,ax            ; get byte count
  3168.     mov    promptbuf[bx],0        ; insert null terminator
  3169.     mov    ax,offset promptbuf
  3170. prom1:    mov    prmptr,ax        ; remember prompt buffer (old/new)
  3171.     clc                ; success
  3172. prom2:    ret
  3173. PROMSET    ENDP
  3174.  
  3175. ; SET SERVER {LOGIN username password | TIMEOUT}
  3176.  
  3177. SETSRV    PROC    NEAR
  3178.     mov    dx,offset srvtab    ; set server table
  3179.     xor    bx,bx            ; use table for help
  3180.     mov    ah,cmkey        ; get keyword
  3181.     call    comnd
  3182.     jnc    setsrv1            ; c = success
  3183.     ret
  3184. setsrv1:cmp    apctrap,0        ; disable from APC?
  3185.     jne    setsrvx            ; ne = yes
  3186.     cmp    bl,1            ; Login?
  3187.     jne    setsrv2            ; ne = no
  3188.     test    flags.remflg,dserver    ; acting as a server now?
  3189.     jz    setsrv3            ; z = no
  3190.     stc                ; fail
  3191.     ret
  3192. setsrv3:mov    bx,offset rdbuf        ; where to store local username
  3193.     mov    dx,offset luserh    ; help
  3194.     mov    comand.cmblen,16    ; buffer length
  3195.     mov    ah,cmword        ; get username
  3196.     call    comnd
  3197.     jc    setsrvx
  3198.     mov    bx,offset rdbuf+30    ; where to store local password
  3199.     mov    dx,offset lpassh    ; help
  3200.     mov    comand.cmblen,16    ; buffer length
  3201.     mov    comand.cmdonum,1    ; \number conversion allowed
  3202.     mov    ah,cmline        ; get password, allow spaces
  3203.     call    comnd
  3204.     jc    setsrvx
  3205.     mov    si,offset rdbuf        ; only now do we transfer to the
  3206.     mov    di,offset luser        ; active buffers
  3207.     call    strcpy
  3208.     mov    si,offset rdbuf+30
  3209.     mov    di,offset lpass
  3210.     call    strcpy
  3211.     clc
  3212.     ret
  3213.  
  3214. setsrv2:mov    min,0            ; Timeout, smallest acceptable value
  3215.     mov    max,255            ; largest acceptable value, one byte
  3216.     mov    numhlp,offset srvthlp    ; help message
  3217.     mov    numerr,0        ; complaint message
  3218.     call    num0            ; parse numerical input
  3219.     jc    setsrvx            ; c = error
  3220.     mov    srvtmo,al        ; store timeout value
  3221.     clc                ; success
  3222. setsrvx:ret
  3223.     
  3224. SETSRV    ENDP
  3225.  
  3226. ; Set REPEAT COUNTS {ON, OFF}
  3227. repset    proc    near
  3228.     mov    dx,offset setrep    ; repeat table
  3229.     xor    bx,bx
  3230.     mov    ah,cmkey
  3231.     call    comnd
  3232.     jnc    repset1
  3233.     ret
  3234. repset1:or    bx,bx            ; which item (counts, prefix)
  3235.     jnz    repset4            ; nz = prefix
  3236.     mov    dx,offset ontab        ; on/off table
  3237.     xor    bx,bx            ; use table for help
  3238.     call    keyend
  3239.     jnc    repset2            ; nc = success
  3240.     ret
  3241. repset2:mov    dtrans.rptqenable,bl    ; repeat quote char enable/disable
  3242.     ret
  3243. repset4:mov    ah,cmword        ; get a character
  3244.     mov    bx,offset rdbuf
  3245.     mov    rdbuf,defrptq        ; default repeat prefix char
  3246.     mov    dx,offset prefhlp
  3247.     call    comnd
  3248.     jc    repset5            ; c = fail
  3249.     push    ax
  3250.     mov    ah,cmeol
  3251.     call    comnd
  3252.     pop    ax
  3253.     jc    repset5            ; c = fail
  3254.     mov    domath_ptr,offset rdbuf
  3255.     mov    domath_cnt,ax
  3256.     mov    domath_msg,1        ; no complaints
  3257.     call    domath            ; convert numerics
  3258.     jc    repset6
  3259.     mov    rdbuf,al
  3260. repset6:mov    al,rdbuf        ; get char
  3261.     call    prechk            ; check range
  3262.     jc    repset5            ; c = failed
  3263.     mov    dtrans.rptq,al        ; set prefix
  3264. repset5:ret
  3265. repset    endp
  3266.  
  3267. ; Check if prefix in AL is in the proper range: 33-62, 96-126. 
  3268. ; Return carry clear if in range, else return carry set.
  3269. prechk    proc    near
  3270.     cmp    al,33
  3271.     jb    prechk2            ; b = out of range
  3272.     cmp    al,62
  3273.     jbe    prechk1            ; be = in range 33-62
  3274.     cmp    al,96
  3275.     jb    prechk2            ; b = out of range
  3276.     cmp    al,126
  3277.     ja    prechk2            ; a = out of range 96-126
  3278. prechk1:clc                ; carry clear for in range
  3279.     ret
  3280. prechk2:stc                ; carry set for out of range
  3281.     ret
  3282. prechk    endp
  3283. ; SET RETRY value. Changes the packet retry limit.
  3284.  
  3285. RETRYSET PROC    NEAR
  3286.     mov    min,1            ; smallest acceptable value
  3287.     mov    max,63            ; largest acceptable value
  3288.     mov    numhlp,offset retryhlp    ; help message
  3289.     mov    numerr,0        ; complaint message
  3290.     call    num0            ; parse numerical input
  3291.     jc    retrys1            ; c = error
  3292.     mov    maxtry,al
  3293. retrys1:ret
  3294. RETRYSET ENDP
  3295.  
  3296. ; Set number of screens in terminal emulator rollback buffer at Kermit
  3297. ; initialization time via Environment. Called by command parser while doing
  3298. ; Environment reading in mssker.asm. Do not call after Kermit has initialized.
  3299. SETROLLB proc    near
  3300.     mov    numhlp,offset rollhlp    ; help
  3301.     mov    numerr,0        ; no error message
  3302.     mov    min,0            ; smallest number
  3303.     mov    max,8000        ; largest magnitude
  3304.     call    num0            ; parse numerical input
  3305.     jc    setrol1            ; c = error
  3306.     mov    npages,ax        ; store result
  3307.     clc
  3308. setrol1:ret
  3309. SETROLLB endp
  3310.  
  3311. ; Set width of rollback screens in terminal emulator rollback buffer at Kermit
  3312. ; initialization time via Environment. Called by command parser while doing
  3313. ; Environment reading in mssker.asm. Do not call after Kermit has initialized.
  3314. SETWIDTH proc    near
  3315.     mov    rollwidth,80        ; default width of rolled screen
  3316.     mov    numhlp,0        ; no help
  3317.     mov    numerr,0        ; no error message
  3318.     mov    min,80            ; smallest number
  3319.     mov    max,207            ; largest magnitude (16 bits worth)
  3320.     call    num0            ; parse numerical input
  3321.     jc    setwid1            ; c = error
  3322.     mov    rollwidth,ax        ; store result
  3323.     clc
  3324. setwid1:ret
  3325. SETWIDTH endp
  3326.  
  3327. ; SET TAKE ECHO or TAKE ERROR on or off
  3328.  
  3329. TAKSET    PROC    NEAR
  3330.     mov    dx,offset taketab    ; Parse a keyword
  3331.     xor    bx,bx            ; no specific help
  3332.     mov    ah,cmkey
  3333.     call    comnd
  3334.     jnc    takset1
  3335.     ret                ; failure
  3336. takset1:push    bx            ; save command indicator
  3337.     mov    dx,offset ontab
  3338.     xor    bx,bx
  3339.     call    keyend
  3340.     pop    ax            ; recover command indicator
  3341.     jnc    takset2
  3342.     ret                ; failure
  3343. takset2:or    al,al            ; Take Echo command?
  3344.     jnz    takset3            ; nz = no
  3345.     mov    flags.takflg,bl
  3346.     clc
  3347.     ret
  3348. takset3:cmp    al,2            ; Take debug command?
  3349.     jne    takset4            ; ne = no
  3350.     mov    flags.takdeb,bl        ; on/off table
  3351.     clc
  3352.     ret
  3353. takset4:mov    takeerror,bl        ; Take Error command
  3354.     clc
  3355.     ret
  3356. TAKSET    ENDP
  3357.  
  3358. ; SET TIMER     on or off during file transfer
  3359.  
  3360. TIMSET    PROC    NEAR
  3361.     mov    dx,offset ontab
  3362.     xor    bx,bx
  3363.     call    keyend
  3364.     jc    timset1            ; c = failure
  3365.     mov    flags.timflg,bl
  3366. timset1:ret
  3367. TIMSET    ENDP
  3368.  
  3369. ; SET WINDOW number of windows
  3370. WINSET    PROC    NEAR
  3371.     mov    min,1            ; smallest acceptable value
  3372.     mov    max,maxwind        ; largest acceptable value
  3373.     mov    numhlp,offset winhelp    ; help message
  3374.     mov    numerr,0        ; complaint message
  3375.     call    num0            ; parse numerical input
  3376.     jc    winse5            ; c = error
  3377.     mov    dtrans.windo,al        ; store default window size
  3378.     mov    trans.windo,al        ; and in active variable for makebuf
  3379.     clc                ; success
  3380. winse5:    ret
  3381. WINSET    ENDP
  3382.  
  3383. ; SET SEND parameters
  3384.  
  3385. SENDSET    PROC    NEAR
  3386.     mov    stflg,'S'        ; Setting SEND parameter 
  3387.     mov    dx,offset stsrtb    ; Parse a keyword
  3388.     xor    bx,bx            ; no specific help
  3389.     mov    ah,cmkey
  3390.     call    comnd
  3391.     jc    sendset1        ; c = failure
  3392.     jmp    bx            ; do the action routine
  3393. sendset1:ret
  3394. SENDSET    ENDP
  3395.  
  3396. ; SET RECEIVE parameters
  3397.  
  3398. recset:    mov    stflg,'R'        ; Setting RECEIVE paramter
  3399.     mov    dx,offset stsrtb    ; Parse a keyword
  3400.     xor    bx,bx            ; no specific help
  3401.     mov    ah,cmkey
  3402.     call    comnd
  3403.     jc    recset1            ; c = failure
  3404.     jmp    bx            ; do the action routine
  3405. recset1:ret
  3406.  
  3407. remset    proc    near            ; Set REMOTE ON/OFF
  3408.     mov    dx,offset ontab
  3409.     mov    bx,offset remhlp
  3410.     call    keyend
  3411.     jc    remset2            ; c = failure
  3412.     and    flags.remflg,not (dquiet+dserial+dregular) ; no display bits
  3413.     or    bl,bl            ; want off state? (same as regular)
  3414.     jz    remset1            ; z = yes
  3415.     or    flags.remflg,dquiet    ; else on = quiet display
  3416.     clc
  3417.     ret
  3418. remset1:or    flags.remflg,dregular    ; off = regular display
  3419.     clc
  3420. remset2:ret
  3421. remset    endp
  3422.  
  3423.  
  3424. ; SET Send and Receive End-of-Packet char
  3425.  
  3426. sreol    PROC    NEAR
  3427.     mov    min,0            ; lowest acceptable value
  3428.     mov    max,1FH            ; largest acceptable value
  3429.     mov    numhlp,offset eophlp    ; help message
  3430.     mov    numerr,0        ; error message address
  3431.     call    num0            ; get numerical input
  3432.     jc    sreol3            ; c = error
  3433.     cmp    stflg,'S'        ; setting SEND paramter?
  3434.     je    sreol1            ; e = yes
  3435.     mov    trans.reol,al
  3436.     mov    dtrans.reol,al
  3437.     jmp    short sreol2
  3438. sreol1:    mov    dtrans.seol,al
  3439. sreol2:    mov    ah,dtrans.seol
  3440.     mov    trans.seol,ah
  3441.     clc
  3442. sreol3:    ret
  3443. sreol    ENDP
  3444.  
  3445.  
  3446. ; SET SEND and RECEIVE start-of-header
  3447.  
  3448. srsoh:    mov    min,0
  3449.     mov    max,7eh            ; allow printables (control=normal)
  3450.     mov    numhlp,offset sohhlp    ; reuse help message
  3451.     mov    numerr,0        ; error message
  3452.     call    num0        ; Common routine for parsing numerical input
  3453.     jc    srsoh2            ; c = error
  3454.     cmp    stflg,'S'        ; setting SEND paramter?
  3455.     je    srsoh1
  3456.     mov    trans.rsoh,al        ; set Receive soh
  3457.     clc                ; success
  3458.     ret
  3459. srsoh1:    mov    trans.ssoh,al        ; set Send soh
  3460.     clc                ; success
  3461.     ret
  3462. srsoh2:    ret
  3463.  
  3464. ; SET Send Double-char
  3465.  
  3466. srdbl    PROC    NEAR
  3467.     mov    min,0            ; lowest acceptable value
  3468.     mov    max,0ffh        ; largest acceptable value
  3469.     mov    numhlp,offset dblhlp    ; help
  3470.     mov    numerr,0        ; error message address
  3471.     call    num0            ; get numerical input
  3472.     jc    sreol3            ; c = error
  3473.     cmp    stflg,'R'        ; setting Receive paramter?
  3474.     je    srdbl1            ; e = yes, no action
  3475.     mov    trans.sdbl,al        ; store character to be doubled
  3476.     mov    dtrans.sdbl,al
  3477.     clc
  3478. srdbl1:    ret
  3479. srdbl    ENDP
  3480.  
  3481. ; SET SEND and    RECEIVE TIMEOUT
  3482.  
  3483. srtim:    mov    min,0
  3484.     mov    max,94
  3485.     mov    numhlp,offset timhlp    ; Reuse help message
  3486.     mov    numerr,0        ; error message
  3487.     call    num0        ; Common routine for parsing numerical input
  3488.     jc    srtim3            ; c = error
  3489.     cmp    stflg,'S'        ; Setting SEND paramter?
  3490.     je    srtim1
  3491.     mov    trans.rtime,al
  3492.     jmp    short srtim2
  3493. srtim1:    mov    dtrans.stime,al
  3494. srtim2:    mov    ah,dtrans.stime
  3495.     mov    trans.stime,ah
  3496.     clc
  3497. srtim3:    ret
  3498.  
  3499. ; SET SEND and RECEIVE PACKET LENGTH
  3500. ; dtrans items are real, trans items are just for SHOW information
  3501.  
  3502. srpack:    mov    min,20
  3503.     mov    max,9024
  3504.     mov    numhlp,offset pakhlp    ; help
  3505.     mov    numerr,offset pakerr    ; error message
  3506.     call    num0
  3507.     jnc    srpaks0            ; nc = success
  3508.     ret                ; failure
  3509. srpaks0:cmp    stflg,'S'        ; setting send value?
  3510.     jne    srpakr            ; ne = receive
  3511.     mov    dtrans.slong,ax        ; set send max value
  3512.     mov    trans.slong,ax        ; store current active length
  3513.     mov    dtrans.spsiz,dspsiz    ; set regular 94 byte default
  3514.     mov    trans.spsiz,dspsiz    ; ditto
  3515.     cmp    ax,dspsiz        ; longer than regular packet?
  3516.     jae    srpaks1            ; ae = yes
  3517.     mov    dtrans.spsiz,al        ; shrink regular packet size too
  3518.     mov    trans.spsiz,al        ; shrink regular packet size too
  3519. srpaks1:clc                ; success
  3520.     ret
  3521.  
  3522. srpakr:    mov    dtrans.rlong,ax        ; set receive max value
  3523.     mov    trans.rlong,ax        ; store active length
  3524.     mov    dtrans.rpsiz,drpsiz    ; set regular to default 94 bytes
  3525.     mov    trans.rpsiz,drpsiz
  3526.     mov    trans.rpsiz,drpsiz
  3527.     cmp    ax,drpsiz        ; longer than a regular packet?
  3528.     jae    srpakr1            ; ae = yes
  3529.     mov    dtrans.rpsiz,al        ; shrink regular packet size too
  3530.     mov    trans.rpsiz,al
  3531. srpakr1:clc                ; success
  3532.     ret
  3533.  
  3534.  
  3535. ; SET SEND and RECEIVE number of padding characters
  3536.  
  3537. srnpd:    mov    min,0
  3538.     mov    max,94
  3539.     mov    numhlp,offset timhlp    ; reuse help message
  3540.     mov    numerr,0        ; error message
  3541.     call    num0            ; Parse numerical input
  3542.     jc    srnpd3            ; c = error
  3543.     cmp    stflg,'S'        ; Setting SEND paramter?
  3544.     je    srnpd1            ; e = yes
  3545.     mov    trans.rpad,al        ; set Receive padding
  3546.     jmp    short srnpd2
  3547. srnpd1:    mov    dtrans.spad,al        ; set default Send padding
  3548. srnpd2:    mov    al,dtrans.spad
  3549.     mov    trans.spad,al        ; update active array for I and S pkts
  3550.     clc
  3551. srnpd3:    ret
  3552.  
  3553. ; SET SEND and RECEIVE padding character
  3554.  
  3555. srpad:    mov    min,0
  3556.     mov    max,127
  3557.     mov    numhlp,offset padhlp
  3558.     mov    numerr,offset padhlp
  3559.     call    num0            ; parse numerical input
  3560.     jc    srpad4            ; c = error
  3561.     cmp    ah,127            ; this is allowed
  3562.     je    srpad1
  3563.     cmp    ah,32
  3564.     jb    srpad1            ; between 0 and 31 is OK too
  3565.     mov    ah,prstr
  3566.     mov    dx,offset padhlp
  3567.     int    dos
  3568. srpad1:    cmp    stflg,'S'        ; Send?
  3569.     je    srpad2            ; e = yes, else Receive
  3570.     mov    trans.rpadch,al        ; store receive pad char
  3571.     jmp    short srpad3
  3572. srpad2:    mov    dtrans.spadch,al    ; store Send pad char
  3573. srpad3:    mov    ah,dtrans.spadch
  3574.     mov    trans.spadch,ah      ; update active array for I and S pkts
  3575.     clc                ; success
  3576. srpad4:    ret
  3577.  
  3578. ; SET SEND and    RECEIVE control character prefix
  3579.  
  3580. srquo:    mov    min,33
  3581.     mov    max,126
  3582.     mov    numhlp,offset quohlp    ; help message
  3583.     mov    numerr,0        ; error message
  3584.     call    num0            ; Parse numerical input
  3585.     jc    srquo3            ; c = error
  3586.     cmp    stflg,'S'        ; Setting outgoing quote char?
  3587.     je    srquo1            ; e = yes
  3588.     mov    trans.rquote,al        ; set Receive quote char
  3589.     jmp    short srquo2
  3590. srquo1:    mov    dtrans.squote,al    ; set Send quote char
  3591. srquo2:    clc
  3592. srquo3:    ret
  3593.  
  3594. ; SET SEND Pause number    of milliseconds
  3595.  
  3596. srpaus:    mov    min,0
  3597.     mov    max,65383
  3598.     mov    numhlp,offset pauhlp    ; help
  3599.     mov    numerr,0
  3600.     call    num0            ; Parse numerical input
  3601.     pushf                ; save carry for error state
  3602.     cmp    stflg,'S'        ; Setting SEND paramter?
  3603.     je    srpau0
  3604.     popf
  3605.     mov    dx,offset ermes5    ; "Not implemented" msg
  3606.     jmp    reterr            ; print error message
  3607. srpau0:    popf
  3608.     jc    srpau1            ; c = error
  3609.     mov    spause,ax        ; store value
  3610. srpau1:    ret
  3611.  
  3612. ; SET SEND/RECEIVE PATHNAMES {off, relative, absolute}
  3613. srpath    proc    near
  3614.     mov    dx,offset pathtab
  3615.     mov    bx,offset rspathhlp
  3616.     call    keyend
  3617.     jc    srpath1
  3618.     cmp    stflg,'R'        ; Setting RECEIVE paramter?
  3619.     jne    srpath1            ; ne = no
  3620.     mov    rcvpathflg,bl        ; update receive flag
  3621.     clc
  3622.     ret
  3623. srpath1:mov    sndpathflg,bl        ; update send flag
  3624.     clc
  3625. srpath2:ret
  3626. srpath    endp
  3627.  
  3628. ; Set stop-bits
  3629. stopbit    proc    near
  3630.     mov    min,1
  3631.     mov    max,2
  3632.     mov    numhlp,offset stophlp    ; help
  3633.     mov    numerr,0
  3634.     call    num0            ; Parse numerical input
  3635.     jnc    stopbit1
  3636.     ret                ; c = failure
  3637. stopbit1:mov    bx,portval
  3638.     mov    [bx].stopbits,al    ; stop bits
  3639.     clc
  3640.     ret    
  3641. stopbit    endp
  3642.  
  3643. ; SET Streaming {on, off}
  3644. strmmode proc    near
  3645.     mov    dx,offset ontab
  3646.     xor    bx,bx
  3647.     call    keyend
  3648.     jnc    strmmod1
  3649.     ret
  3650. strmmod1:mov    streaming,bl        ; update streaming flag
  3651.     ret
  3652. strmmode endp
  3653.  
  3654. ; SET TCP/IP address nnn.nnn.nnn.nnn
  3655. ; SET TCP/IP subnetmask nnn.nnn.nnn.nnn
  3656. ; SET TCP/IP gateway nnn.nnn.nnn.nnn
  3657. ; SET TCP/IP primary-nameserver nnn.nnn.nnn.nnn
  3658. ; SET TCP/IP secondary-nameserver nnn.nnn.nnn.nnn
  3659. ; SET TCP/IP domain string
  3660.  
  3661. ifndef    no_tcp
  3662. tcpipset proc    near
  3663.     mov    ah,cmkey        ; get keyword
  3664.     mov    dx,offset tcptable    ; table
  3665.     xor    bx,bx            ; help
  3666.     call    comnd
  3667.     jnc    tcpse1
  3668.     ret
  3669. tcpse1:    mov    word ptr rdbuf,bx    ; keyword index
  3670.     mov    comand.cmblen,17    ; length of user's buffer
  3671.     cmp    bx,1            ; local address?
  3672.     jne    tcpse1a            ; ne = no
  3673.     mov    dx,offset addrhelp    ; address help
  3674.     jmp    short tcpse4
  3675. tcpse1a:cmp    bx,2            ; domain name?
  3676.     jne    tcpse2            ; ne = no
  3677.     mov    dx,offset domainhlp    ; domain help
  3678.     mov    comand.cmblen,32    ; length of user's buffer
  3679.     jmp    short tcpse4
  3680. tcpse2:    cmp    bx,3            ; subnet mask?
  3681.     jne    tcpse3            ; ne = no
  3682.     mov    dx,offset subnethlp
  3683.     jmp    short tcpse4
  3684. tcpse3:    cmp    bx,7            ; Host?
  3685.     jne    tcpse3a            ; ne = no
  3686.     mov    dx,offset hosthlp
  3687.     mov    comand.cmblen,60    ; length of user's buffer
  3688.     jmp    short tcpse4
  3689. tcpse3a:cmp    bx,9            ; PD interrupt?
  3690.     jne    tcpse3b            ; ne = no
  3691.     mov    dx,offset tcppdinthlp
  3692.     jmp    short tcpse4
  3693. tcpse3b:cmp    bx,10            ; term type?
  3694.     jne    tcpse3c            ; ne = no
  3695.     mov    dx,offset tcpttyhlp
  3696.     mov    comand.cmblen,32    ; length of user's buffer
  3697.     jmp    short tcpse4
  3698. tcpse3c:cmp    bx,11            ; newline mode?
  3699.     jne    tcpse3d            ; ne = no
  3700.     jmp    tcpse13
  3701. tcpse3d:cmp    bx,12            ; debug mode?
  3702.     jne    tcpse3e            ; ne = no
  3703.     jmp    tcpse14
  3704. tcpse3e:cmp    bx,13            ; binary/nvt mode?
  3705.     jne    tcpse3f            ; ne = no
  3706.     jmp    tcpse15
  3707. tcpse3f:cmp    bx,14            ; MSS?
  3708.     jne    tcpse3g            ; ne = no
  3709.     jmp    tcpse16
  3710.  
  3711. tcpse3g:mov    dx,offset iphelp    ; Internet number help
  3712. tcpse4:    mov    ah,cmword        ; get a string
  3713.     mov    bx,offset rdbuf+2    ; work buffer
  3714.     call    comnd
  3715.     jnc    tcpse5
  3716.     ret
  3717. tcpse5:    push    ax            ; save string length in ax
  3718.     mov    ah,cmeol
  3719.     call    comnd
  3720.     pop    ax
  3721.     jnc    tcpse6
  3722.     ret
  3723. tcpse6:    mov    si,offset rdbuf+2    ; user's string
  3724.     mov    bx,word ptr rdbuf    ; comand kind
  3725.     cmp    bx,2            ; domain?
  3726.     jne    tcpse8            ; ne = no
  3727.     mov    di,offset tcpdomain
  3728.     cmp    ax,32            ; exceeded 32 chars?
  3729.     jbe    tcpse7            ; be = no
  3730.     mov    ah,prstr
  3731.     mov    dx,offset domainbad    ; compain
  3732.     int    dos
  3733.     stc
  3734.     ret
  3735. tcpse7:    cmp    ax,32            ; address oversized?
  3736.     jbe    tcpse9            ; be = no
  3737.     mov    ah,prstr
  3738.     mov    dx,offset addressbad    ; say bad address
  3739.     int    dos
  3740.     stc
  3741.     ret
  3742. tcpse8:    mov    di,offset tcpaddress
  3743.     cmp    bx,1            ; local address?
  3744.     je    tcpse9            ; e = yes
  3745.     mov    di,offset tcpsubnet
  3746.     cmp    bx,3            ; subnet?
  3747.     je    tcpse9            ; e = yes
  3748.     mov    di,offset tcpgateway
  3749.     cmp    bx,4            ; gateway?
  3750.     je    tcpse9
  3751.     mov    di,offset tcpprimens
  3752.     cmp    bx,5            ; primary-nameserver?
  3753.     je    tcpse9
  3754.     mov    di,offset tcpsecondns    ; secondary-nameserer
  3755.     cmp    bx,6
  3756.     je    tcpse9
  3757.     mov    di,offset tcphost    ; host name or number
  3758.     cmp    bx,7
  3759.     je    tcpse9
  3760.     mov    di,offset tcpbcast    ; broadcast
  3761. tcpse9:    cmp    bx,9            ; port or other?
  3762.     jae    tcpse10            ; ae = yes
  3763.     call    strcpy
  3764.     clc
  3765.     ret
  3766. tcpse10:cmp    bx,9            ; PD interrupt?
  3767.     jne    tcpse12            ; ne = no
  3768.     mov    si,offset rdbuf+2
  3769. tcpse11:mov    ax,word ptr [si]
  3770.     and    ax,not 2020h        ; to upper case
  3771.     cmp    ax,'DO'            ; ODI?
  3772.     je    tcpse11a        ; e = yes, use "DO"
  3773.     push    bx
  3774.     mov    domath_ptr,si
  3775.     mov    domath_cnt,16
  3776.     call    domath            ; convert to number in ax
  3777.     pop    bx
  3778. tcpse11a:mov    tcppdint,ax
  3779.     clc
  3780.     ret
  3781. tcpse12:cmp    bx,10            ; term-type string?
  3782.     jne    tcpse13            ; ne = no
  3783.     mov    si,offset rdbuf+2
  3784.     mov    di,offset tcpttbuf    ; copy string to holding place
  3785.     call    strcpy
  3786.     clc
  3787.     ret
  3788. tcpse13:cmp    bx,11            ; newline mode?
  3789.     jne    tcpse14            ; ne = no
  3790.     mov    dx,offset newlinetab    ; newline table
  3791.     mov    bx,offset tcpnlhlp    ; help
  3792.     call    keyend
  3793.     jc    tcpse20            ; fail
  3794.     mov    tcpnewline,bl        ; set mode
  3795.     clc
  3796.     ret
  3797. tcpse14:cmp    bx,12            ; debug mode?
  3798.     jne    tcpse15            ; ne = no
  3799.     mov    dx,offset tcpdbtab
  3800.     xor    bx,bx            ; help
  3801.     call    keyend
  3802.     jc    tcpse20            ; fail
  3803.     mov    tcpdebug,bl        ; set mode
  3804.     clc
  3805.     ret
  3806. tcpse15:cmp    bx,13            ; binary/nvt mode?
  3807.     jne    tcpse16            ; ne = no
  3808.     mov    dx,offset tcpmodetab    ; mode table
  3809.     xor    bx,bx            ; help
  3810.     call    keyend
  3811.     jc    tcpse20
  3812.     mov    tcpmode,bl        ; set mode
  3813.     clc
  3814.     ret
  3815. tcpse16:cmp    bx,14            ; MSS?
  3816.     jne    tcpse20            ; ne = no
  3817.     mov    numhlp,offset tcpmsshlp    ; help
  3818.     mov    min,16            ; get decimal value
  3819.     mov    max,1460        ; range is 16 to 1460 decimal
  3820.     mov    numerr,0        ; error message
  3821.     call    num0            ; convert number, return it in ax
  3822.     jc    tcpse20            ; c = error
  3823.     mov    tcpmss,ax        ; MSS
  3824.     clc
  3825.     ret
  3826. tcpse20:stc                ; fail
  3827.     ret
  3828. tcpipset endp
  3829. endif    ; no_tcp
  3830.  
  3831. ; SET TRANSFER  CHARACTER-SET {Latin1, Shift-JIS, Transparent}
  3832. ; SET TRANSFER  TRANSLATION {Readable, Invertible}
  3833. ; SET TRANSFER  MODE {Automatic, Manual}
  3834. sxfer    proc    near
  3835.     mov    dx,offset xfertab    ; table of TRANSFER keywords
  3836.     xor    bx,bx
  3837.     mov    ah,cmkey        ; get next keyword
  3838.     call    comnd
  3839.     jc    sxfer1            ; c = error
  3840.     or    bl,bl            ; Character-set?
  3841.     jnz    sxfer2            ; nz = no
  3842.     mov    dx,offset xfchtab    ; Character-set table
  3843.     mov    bx,offset xfchhlp    ; help text
  3844.     call    keyend
  3845.     jc    sxfer1            ; c = error
  3846.     mov    dtrans.xchset,bl    ; store transfer char set ident
  3847.     mov    trans.xchset,bl        ; store transfer char set ident
  3848.     cmp    bl,xfr_cyrillic        ; Cyrillic?
  3849.     jne    sxfer9            ; ne = no
  3850.     mov    ax,flags.chrset        ; get current file character set
  3851.     mov    flags.chrset,866    ; force CP866
  3852.     cmp    ax,866            ; was CP866/LATIN5 File Character set?
  3853.     je    sxfer8            ; e = yes
  3854.     mov    dx,offset xfchbad    ; show warning message
  3855.     mov    ah,prstr
  3856.     int    dos
  3857. sxfer8:    clc
  3858. sxfer1:    ret
  3859. sxfer9:    cmp    bl,xfr_japanese        ; Japanese-EUC?
  3860.     jne    sxfer10            ; ne = no
  3861.     mov    ax,flags.chrset        ; get current file character set
  3862.     mov    flags.chrset,932    ; force Shift-JIS
  3863.     cmp    ax,932            ; was Shift-JIS File Character set?
  3864.     je    sxfer8            ; e = yes
  3865.     mov    dx,offset xfchbad2    ; show warning message
  3866.     mov    ah,prstr
  3867.     int    dos
  3868.     clc
  3869.     ret
  3870. sxfer10:cmp    bl,xfr_hebiso        ; Hebrew-ISO?
  3871.     jne    sxfer8            ; ne = no
  3872.     mov    ax,flags.chrset        ; get current file character set
  3873.     mov    flags.chrset,862    ; force CP 862
  3874.     cmp    ax,862            ; was CP862 the File Character set?
  3875.     je    sxfer8            ; e = yes
  3876.     mov    dx,offset xfchbad3    ; show warning message
  3877.     mov    ah,prstr
  3878.     int    dos
  3879.     clc
  3880.     ret
  3881.  
  3882. sxfer2:    cmp    bx,1            ; LOCKING-SHIFT?
  3883.     jne    sxfer3            ; ne = no
  3884.     mov    dx,offset xfertab1    ; off, on, forced table
  3885.     mov    bx,offset xferhlp1
  3886.     call    keyend
  3887.     jc    sxfer1
  3888.     mov    dtrans.lshift,bl    ; save state
  3889.     mov    trans.lshift,bl
  3890.     clc
  3891.     ret
  3892. sxfer3:    cmp    bx,2            ; Translation table?
  3893.     jne    sxfer4            ; ne = no
  3894.     mov    dx,offset xfertab2    ; TRANSLATION table
  3895.     mov    bx,offset xfchhlp2    ; help text
  3896.     call    keyend
  3897.     jc    sxfer1            ; c = error
  3898.     mov    dtrans.xchri,bl        ; store readable/invertible flag
  3899.     mov    trans.xchri,bl
  3900.     clc
  3901.     ret
  3902. sxfer4:    cmp    bx,3            ; MODE?
  3903.     jne    sxfer5            ; ne = no
  3904.     mov    dx,offset xfertab3    ; MODE table
  3905.     mov    bx,offset xferhlp3    ; help text
  3906.     call    keyend
  3907.     jc    sxfer1            ; c = error
  3908.     mov    dtrans.xmode,bl        ; store file transfer mode sensing
  3909.     mov    trans.xmode,bl
  3910.     clc
  3911.     ret
  3912.  
  3913. sxfer5:    cmp    bl,4            ; CRC?
  3914.     jne    sxfer6            ; ne = no
  3915.     mov    dx,offset ontab        ; on/off table
  3916.     xor    bx,bx
  3917.     call    keyend
  3918.     jc    sxfer6            ; c = error
  3919.     mov    dtrans.xcrc,bl        ; store crc usage
  3920.     mov    trans.xcrc,bl
  3921.     clc
  3922.     ret
  3923. sxfer6:    stc                ; fail
  3924.     ret
  3925. sxfer    endp
  3926.  
  3927. ; SET TRANSLATION           Connect mode translate characters
  3928. ; SET TRANSLATION INPUT {Original-byte New-byte | ON | OFF}
  3929. ; SET TRANSLATION KEYBOARD {ON | OFF}, default is ON
  3930.  
  3931. SETRX    PROC    NEAR            ; translate incoming serial port char
  3932.     mov    ah,cmkey
  3933.     mov    dx,offset trnstab    ; direction table (just one entry)
  3934.     xor    bx,bx            ; no help
  3935.     call    comnd
  3936.     jnc    setrx0            ; nc = success
  3937.     ret                ; failure
  3938. setrx0:    cmp    bx,2            ; Keyboard?
  3939.     jne    setrx0b            ; ne = no
  3940.     jmp    setr11            ; do keyboard
  3941. setrx0b:mov    bx,offset rdbuf        ; our work space
  3942.     mov    dx,offset srxhlp1    ; first help message
  3943.     mov    ah,cmword        ; parse a word
  3944.     call    comnd            ; get incoming byte pattern
  3945.     jnc    setrx0a            ; nc = success
  3946.     ret
  3947. setrx0a:or    ax,ax            ; any text given?
  3948.     jz    setr6            ; nz = no
  3949.     mov    temp,ax            ; save byte count here
  3950.     mov    ax,word ptr rdbuf    ; get first two characters
  3951.     or    ax,2020h        ; convert upper to lower case
  3952.     cmp    ax,'fo'            ; first part of word OFF?
  3953.     je    setr6            ; e = yes, go analyze
  3954.     cmp    ax,'no'            ; word ON?
  3955.     je    setr6            ; e = yes, go do it
  3956.     mov    domath_ptr,offset rdbuf
  3957.     mov    domath_cnt,16
  3958.     mov    domath_msg,1        ; stop messages
  3959.     call    domath            ; convert to number in ax
  3960.     jnc    setr1            ; nc = success    
  3961.     mov    ax,word ptr rdbuf
  3962.     cmp    temp,1            ; just one character given?
  3963. ;;;;;;;    jne    setr6            ; ne = no, so bad code
  3964. setr1:    mov    min,ax            ; save byte code here
  3965.     mov    bx,offset rdbuf        ; our work space
  3966.     mov    dx,offset srxhlp1    ; first help message
  3967.     mov    ah,cmword        ; parse a word
  3968.     call    comnd            ; get incoming byte pattern
  3969.     jnc    setr2            ; nc = success
  3970.     ret                ; failure
  3971. setr2:    or    ax,ax            ; any text given?
  3972.     jz    setr6            ; z = no
  3973.     mov    temp,ax            ; save byte count here
  3974.     mov    domath_ptr,offset rdbuf
  3975.     mov    domath_cnt,ax
  3976.     mov    domath_msg,1        ; stop messages
  3977.     call    domath            ; convert to number in ax
  3978.     jnc    setr3            ; nc = success
  3979.     mov    ax,word ptr rdbuf
  3980.     cmp    temp,1            ; just one character given?
  3981. ;;;;;    jne    setr6            ; ne = no, so bad code or ON/OFF
  3982. setr3:    mov    max,ax            ; save byte code here
  3983.     mov    ah,cmeol        ; get a confirm
  3984.     call    comnd
  3985.     jnc    setr3a            ; nc = success
  3986.     ret                ; failure
  3987. setr3a:    mov    bx,min            ; bl = incoming byte code
  3988.     xor    bh,bh
  3989.     mov    ax,max            ; al = local (translated) byte code
  3990.     mov    rxtable [bx],al        ; store in rx translate table
  3991.     clc                ; success
  3992.     ret
  3993.  
  3994. setr6:    mov    ah,cmeol        ; get a confirm
  3995.     call    comnd
  3996.     jnc    setr6a            ; nc = success
  3997.     ret                ; failure
  3998. setr6a:    mov    dx,offset badrx        ; assume bad construction
  3999.     or    word ptr rdbuf,2020h    ; convert to lower case
  4000.     or    rdbuf+2,20h        ; first three chars
  4001.     cmp    word ptr rdbuf,'fo'    ; key word OFF?
  4002.     jne    setr8            ; ne = no
  4003.     cmp    rdbuf+2,'f'        ; last letter of OFF?
  4004.     jne    setr8            ; ne = no
  4005.     mov    rxtable+256,0        ; OFF is status byte = zero
  4006.     mov    dx,offset rxoffmsg    ; say translation is turned off
  4007.     jmp    short setr9
  4008. setr8:    cmp    word ptr rdbuf,'no'    ; keyword ON?
  4009.     jne    setr9a            ; ne = no, error
  4010.     mov    rxtable+256,1        ; ON is status byte non-zero
  4011.     mov    dx,offset rxonmsg    ; say translation is turned on
  4012. setr9:    cmp    taklev,0        ; executing from a Take file?
  4013.     je    setr9a            ; e = no
  4014.     cmp    flags.takflg,0        ; echo contents of Take file?
  4015.     je    setr10            ; e = no
  4016. setr9a:    mov    ah,prstr        ; bad number message
  4017.     int    dos
  4018. setr10:    clc
  4019.     ret
  4020. setr11:    mov    ah,cmkey        ; SET TRANSLATION KEYBOARD
  4021.     mov    dx,offset ontab        ; on/off
  4022.     xor    bx,bx
  4023.     call    comnd
  4024.     jnc    setr12            ; nc = success
  4025.     ret
  4026. setr12:    push    bx
  4027.     mov    ah,cmeol        ; get a confirm
  4028.     call    comnd
  4029.     pop    bx
  4030.     jnc    setr13            ; nc = success
  4031.     ret                ; failure
  4032. setr13:    mov    flags.xltkbd,bl        ; set keyboard translation on/off
  4033.     clc
  4034.     ret
  4035. SETRX    ENDP
  4036.  
  4037. ; SET TRANSMIT {FILL, LF, Prompt} {ON, OFF, or value}
  4038. SETXMIT    proc    near
  4039.     mov    dx,offset xmitab    ; TRANSMIT keyword table
  4040.     xor    bx,bx
  4041.     mov    ah,cmkey        ; get keyword
  4042.     call    comnd
  4043.     jnc    setxmi1            ; nc = success
  4044.     ret
  4045. setxmi1:cmp    bl,2            ; SET TRANSMIT PROMPT?
  4046.     jne    setxmi2            ; ne = no
  4047.     mov    ah,cmword
  4048.     mov    bx,offset rdbuf        ; put answer here
  4049.     mov    dx,offset xpmthlp
  4050.     call    comnd
  4051.     jc    setxmi1d        ; c = error
  4052.     push    ax            ; save length
  4053.     mov    ah,cmeol        ; get a confirm
  4054.     call    comnd
  4055.     pop    cx            ; recover length to cx
  4056.     jc    setxmi1d        ; c = failure
  4057.     mov    al,rdbuf
  4058.     cmp    cx,1            ; a single char?
  4059.     je    setxmi1c        ; e = yes, use it as the prompt char
  4060.     mov    domath_ptr,offset rdbuf
  4061.     mov    domath_cnt,cx
  4062.     call    domath            ; convert to number in ax
  4063.     jc    setxmi1d        ; c = no number, error
  4064. setxmi1c:mov    script.xmitpmt,al    ; store new prompt value
  4065. setxmi1d:ret
  4066.  
  4067. setxmi2:cmp    bl,1            ; LF?
  4068.     jne    setxmi3            ; ne = no
  4069.     mov    dx,offset ontab        ; on or off table
  4070.     xor    bx,bx
  4071.     call    keyend
  4072.     jc    setxmi2a        ; c = failure
  4073.     mov    script.xmitlf,bl    ; set the xmitlf flag
  4074. setxmi2a:ret
  4075.  
  4076. setxmi3:cmp    bl,0            ; FILL?
  4077.     jne    setxmi8            ; ne = no
  4078.     mov    ah,cmword        ; FILL, get a word sized token
  4079.     mov    bx,offset rdbuf        ; put it here
  4080.     mov    dx,offset xfilhlp    ; help
  4081.     call    comnd
  4082.     jc    setxmix            ; c = failure
  4083.     push    ax            ; save length in ah
  4084.     mov    ah,cmeol        ; get a confirm
  4085.     call    comnd
  4086.     pop    ax
  4087.     jc    setxmix            ; c = failure
  4088.     cmp    ax,1            ; just one character?
  4089.     ja    setxmi4            ; a = no, there's more
  4090.     mov    al,rdbuf        ; get the char
  4091.     mov    script.xmitfill,al    ; store Fill char
  4092.     ret
  4093. setxmi4:mov    ax,word ptr rdbuf
  4094.     or    ax,2020h        ; to lower
  4095.     cmp    ax,'on'            ; "none"?
  4096.     jne    setxmi5            ; ne = no
  4097.     mov    script.xmitfill,0    ; no Filling
  4098.     ret
  4099. setxmi5:cmp    ax,'ps'            ; "space"?
  4100.     jne    setxmi6            ; ne = no
  4101.     mov    script.xmitfill,' '    ; use space as filler
  4102.     ret
  4103. setxmi6:mov    domath_ptr,offset rdbuf
  4104.     mov    domath_cnt,17
  4105.     call    domath            ; convert to number in ax
  4106.     jc    setxmix            ; c = no number, error
  4107.     mov    script.xmitfill,al    ; set the xmitfill flag
  4108.     ret
  4109. setxmi8:mov    ah,cmword        ; PAUSE milliseconds
  4110.     mov    bx,offset rdbuf        ; put answer here
  4111.     mov    dx,offset xpauhlp
  4112.     call    comnd
  4113.     jc    setxmix            ; c = error
  4114.     push    ax            ; save length
  4115.     mov    ah,cmeol        ; get a confirm
  4116.     call    comnd
  4117.     pop    cx            ; recover length to cx
  4118.     jc    setxmix            ; c = failure
  4119.     mov    domath_ptr,offset rdbuf
  4120.     mov    domath_cnt,cx
  4121.     call    domath            ; convert to number in ax
  4122.     jc    setxmix            ; c = no number, error
  4123.     mov    script.xmitpause,ax    ; set the xmitpause flag
  4124. setxmix:ret
  4125. SETXMIT    endp
  4126.  
  4127. ; SET UNKNOWN-CHARACTER-SET {DISCARD, KEEP}, default is KEEP
  4128. unkchset proc    near
  4129.     mov    dx,offset unkctab    ; keep/reject keyword table
  4130.     mov    bx,offset unkchhlp
  4131.     call    keyend
  4132.     jc    unkchx            ; c = failure
  4133.     mov    flags.unkchs,bl        ; 0 = keep, else reject
  4134. unkchx:    ret
  4135. unkchset endp
  4136.  
  4137. ; Common routine for parsing numerical input
  4138. ; Enter with numhlp = offset of help message, numerr = offset of optional
  4139. ;  error message, min, max = allowable range of values.
  4140. ; Returns value in ax, or does parse error return.
  4141. ; Changes ax,bx,dx,si.            [jrd] 18 Oct 1987
  4142. num0:    mov    bx,offset rdbuf        ; where to put text
  4143.     mov    dx,numhlp        ; help text
  4144.     mov    ah,cmword        ; get a word
  4145.     call    comnd
  4146.     push    ax            ; save string count
  4147.     mov    ah,cmeol
  4148.     call    comnd            ; Get a confirm
  4149.     pop    ax
  4150.     jc    num0x            ; c = failure
  4151.     call    numwd
  4152. num0x:    ret
  4153.                     ; second entry point
  4154.  
  4155. ; routine to print an error message, then exit without error status
  4156. ; expects message in dx
  4157. reterr    proc    near
  4158.     mov    ah,prstr
  4159.     int    dos
  4160.     clc
  4161.     ret
  4162. reterr    endp
  4163.  
  4164. code    ends
  4165.  
  4166. code1    segment
  4167.  
  4168. ; Add an entry to a keyword table
  4169. ; enter with bx = table address, dx = ptr to new entry, macptr = string seg,
  4170. ; mccptr = offset of free bytes in table mcctab.
  4171. ; no check is made to see if the entry fits in the table.
  4172. addtab    proc    far
  4173.     push    cx
  4174.     push    si
  4175.     push    es
  4176.     push    bp
  4177.     cld
  4178.     mov    ax,ds
  4179.     mov    es,ax        ; address data segment
  4180.     mov    bp,bx        ; remember where macro name table starts
  4181.     mov    cl,[bx]        ; pick up length of table
  4182.     xor    ch,ch
  4183.     inc    bx        ; point to actual table
  4184.     jcxz    addta4        ; cx = 0 if table is presently empty
  4185.  
  4186. addta1:    push    cx        ; preserve count
  4187.     mov    si,dx        ; point to entry
  4188.     lodsw            ; get length of new entry
  4189.     mov    cx,[bx]        ; and length of table entry
  4190.     cmp    ax,cx        ; are they the same?
  4191.     lahf            ; remember result of comparison
  4192.     jae    addta2        ; is new smaller? ae = no, use table length
  4193.     mov    cx,ax        ; else use length of new entry
  4194. addta2:    lea    di,[bx+2]    ; point to actual keyword
  4195.     repe    cmpsb        ; compare strings
  4196.     pop    cx        ; restore count
  4197.     jb    addta4        ; below, insert before this one
  4198.     jne    addta3        ; not below or same, keep going
  4199.     sahf            ; same. get back result of length comparison
  4200.     jb    addta4        ; if new len is smaller, insert here
  4201.     jne    addta3        ; if not same size, keep going
  4202.     mov    si,bx        ; else this is where entry goes
  4203.     jmp    short addta6    ; no insertion required
  4204. addta3:    mov    ax,[bx]        ; length of keyword
  4205.     add    bx,ax        ; skip this entry
  4206.     add    bx,4        ; length word and 16 bit value
  4207.     loop    addta1        ; and keep looking
  4208. addta4:    mov    si,bx        ; this is first location to move
  4209.     mov    di,bx
  4210.     inc    ds:byte ptr [bp] ; remember we're adding one
  4211.     jcxz    addta6        ; z = no more entries, forget this stuff
  4212. addta5:    mov    bx,[di]        ; get length
  4213.     lea    di,[bx+di+4]    ; end is origin + length + 4 for len, value
  4214.     loop    addta5        ; loop thru remaining keywords
  4215.     mov    cx,di
  4216.     sub    cx,si        ; compute # of bytes to move
  4217.     push    si        ; preserve loc for new entry
  4218.     mov    si,di        ; first to move is last
  4219.     dec    si        ; minus one
  4220.     mov    di,dx        ; new entry
  4221.     mov    bx,[di]        ; get length
  4222.     lea    di,[bx+si+4]    ; dest is source + length of new + 4
  4223.     std            ; move backward
  4224.     rep    movsb        ; move the table down (compress it)
  4225.     cld            ; put flag back
  4226.     pop    si
  4227. addta6:    mov    di,si        ; this is where new entry goes
  4228.     mov    si,dx        ; this is where it comes from
  4229.     mov    cx,[si]        ; length of name
  4230.     add    cx,2        ; include count byte
  4231.     add    mccptr,cx    ; update free space pointer: cnt+name
  4232.     rep    movsb        ; insert new entry
  4233.     mov    ax,macptr    ; and string address
  4234.     stosw
  4235.     add    mccptr,2    ; plus string address
  4236.     pop    bp
  4237.     pop    es
  4238.     pop    si
  4239.     pop    cx
  4240.     ret
  4241. addtab    endp
  4242.  
  4243. ; If new keyword matches an existing one then remove existing keyword,
  4244. ; its string definition, compress tables mcctab and macbuf, readjust string
  4245. ; pointers for each macro name, reduce number of macro table entries by one.
  4246. ; Enter with DI pointing at length word of mac name (followed by mac name).
  4247. ; Otherwise, exit with no changes.  13 June 1987 [jrd]
  4248. remtab    proc    far
  4249.     push    ax
  4250.     push    bx
  4251.     push    cx
  4252.     push    si
  4253.     push    di
  4254.     push    temp            ; preserve
  4255.     mov    bx,offset mcctab+1    ; table of macro keywords
  4256.     mov    temp,0            ; temp = current keyword
  4257.     cmp    byte ptr mcctab,0    ; any macros defined?
  4258.     jne    remta1            ; ne = yes
  4259.     jmp    remtax            ; else exit now
  4260. remta1:                    ; match table keyword and text word
  4261.     mov    si,di            ; pointer to user's cnt+name
  4262.     mov    cx,[si]            ; length of user's macro name
  4263.     jcxz    remtax            ; empty macro name to remove
  4264.     add    si,2            ; point to new macro name
  4265.     cmp    cx,[bx]            ; compare length vs table keyword
  4266.     jne    remta4            ; ne = not equal lengths, try another
  4267.     push    si            ; lengths match, how about spelling?
  4268.     push    bx
  4269.     add    bx,2            ; point at start of keyword
  4270. remta2:    mov    ah,[bx]            ; keyword char
  4271.     mov    al,[si]            ; new text char
  4272.     cmp    al,ah            ; test characters
  4273.     jne    remta3            ; ne = no match
  4274.     inc     si            ; move to next char
  4275.     inc    bx
  4276.     loop    remta2            ; loop through entire length
  4277. remta3:    pop    bx
  4278.     pop    si
  4279.     jcxz    remta6            ; z: cx = 0, exit with match;
  4280.                     ;  else select next keyword
  4281. remta4:    inc    temp            ; number of keyword to test next
  4282.     mov    cx,temp
  4283.     cmp    cl,mcctab        ; all done? Recall, temp starts at 0
  4284.     jb    remta5            ; b = not yet
  4285.     jmp    remtax            ; exhausted search, unsuccessfully
  4286. remta5:    mov    ax,[bx]            ; cnt (keyword length from macro)
  4287.     add    ax,4            ; skip count and word pointer
  4288.     add    bx,ax            ; bx = start of next keyword slot
  4289.     jmp    short remta1        ; do another comparison
  4290.                     ; new name already present as a macro
  4291. remta6:    cld                ; clear macro string and macro name
  4292.     push    ds
  4293.     pop    es            ; set es to data segment
  4294.     mov    temp,bx            ; save ptr to found keyword
  4295.     mov    ax,[bx]            ; cnt (keyword length of macro)
  4296.     add    ax,2            ; skip cnt
  4297.     add    bx,ax            ; point to string segment field
  4298.     add    ax,2            ; count segment field bytes
  4299.     sub    mccptr,ax        ; readjust free space ptr for names
  4300.     push    bx
  4301.     push    es
  4302.     mov    es,[bx]            ; segment of string
  4303.     mov    ax,ds            ; check for being in our data segment
  4304.     cmp    ax,[bx]            ; same as our data seg?
  4305.     je    remta7            ; e = yes, don't free that
  4306.     mov    ah,freemem        ; free that memory block
  4307.     int    dos
  4308. remta7:    pop    es
  4309.     pop    bx
  4310.                     ; clear keyword table mcctab
  4311.     add    bx,2            ; compute source = next keyword
  4312.     mov    si,bx            ; address of next keyword
  4313.     mov    di,temp            ; address of found keyword
  4314.     mov    cx,offset mcctab+mcclen ; address of buffer end
  4315.     sub    cx,si            ; amount to move
  4316.     jcxz    remtax            ; cx = 0 means none
  4317.     rep    movsb            ; move down keywords (deletes current)
  4318.     dec    mcctab            ; one less keyword
  4319. remtax:    pop    temp            ; recover temp variable
  4320.     pop    di
  4321.     pop    si
  4322.     pop    cx
  4323.     pop    bx
  4324.     pop    ax
  4325.     ret
  4326. remtab    endp
  4327.  
  4328. ; Renames macros \%0..\%9 by changing the first two characters of the name
  4329. ; to be <null><taklev>. Used to preserve old \%n macros and not show them.
  4330. ; Return carry set if nothing is hidden.
  4331. hidemac proc    far
  4332.     push    bx
  4333.     push    cx
  4334.     push    temp
  4335.     mov    hidetmp,0        ; use binary 0 prefix
  4336.     mov    byte ptr temp,'0'    ; start with this \%0 name
  4337. hidema1:mov    bx,offset mcctab+1    ; table of macro names, skip count
  4338.     mov    cl,mcctab        ; number of entries
  4339.     xor    ch,ch
  4340.     jcxz    hidema6            ; z = empty table
  4341.  
  4342. hidema2:cmp    word ptr [bx],3        ; name length, do three byte names
  4343.     jne    hidema3            ; ne = not three chars
  4344.     cmp    word ptr [bx+2],'%\'    ; starts with correct prefix?
  4345.     jne    hidema3            ; ne = no
  4346.     mov    al,byte ptr [bx+4]    ; third char of name
  4347.     cmp    al,byte ptr temp    ; matches name?
  4348.     je    hidema4            ; e = yes
  4349. hidema3:mov    ax,[bx]            ; get length of name
  4350.     add    ax,4            ; plus count and word pointer
  4351.     add    bx,ax            ; point to next entry
  4352.     loop    hidema2
  4353.     jmp    short hidema5
  4354. hidema4:call    hidewrk            ; call worker to hide macro
  4355. hidema5:inc    byte ptr temp
  4356.     cmp    byte ptr temp,'9'    ; all done?
  4357.     jbe    hidema1            ; be = no
  4358. hidema6:pop    temp
  4359.     pop    cx
  4360.     pop    bx
  4361.     ret
  4362. hidemac    endp
  4363.  
  4364. ; Hide existing macro. Enter with BX pointing to entry slot in mcctab,
  4365. ; uses settemp as temp workspace.
  4366. ; Used by hidemac and localmac. 
  4367. hidewrk    proc    far
  4368.     push    bx
  4369.     push    cx
  4370.     push    si
  4371.     push    di
  4372.     mov    di,bx            ; need di for remtab
  4373.     mov    ax,[bx]            ; original count word
  4374.     mov    cx,ax
  4375.     add    ax,2            ; plus new prefix
  4376.     mov    si,offset settemp
  4377.     mov    [si],ax            ; len = old length plus <null><level>
  4378.     xor    al,al            ; prepare new prefix
  4379.     mov    al,hidetmp        ;  use 0..9 binary
  4380.     mov    ah,taklev        ; of <null><taklev>
  4381.     mov    [si+2],ax        ; new prefix
  4382.     add    si,4            ; count and prefix
  4383. hidewr1:mov    al,[bx+2]        ; copy old name after prefix
  4384.     mov    [si],al
  4385.     inc    bx
  4386.     inc    si
  4387.     loop    hidewr1
  4388.  
  4389.           mov    bx,di
  4390.     mov    ax,[bx]            ; length of name
  4391.     add    ax,2            ; plus name length count word
  4392.     add    bx,ax            ; point at definition segment
  4393.     mov    ax,1            ; smallest allocation
  4394.     call    malloc            ; allocate space as dummy definition
  4395.     mov    cx,[bx]            ; seg of original def to CX
  4396.     mov    [bx],ax            ; seg of dummy def replaces it
  4397.     call    remtab            ; remove macro, di is pointer
  4398.     mov    macptr,cx        ; tell addtab definition segment
  4399.     mov    bx,offset mcctab     ; macro name table
  4400.     mov    dx,offset settemp    ; new name
  4401.     call    addtab        ; create new entry for <null><digit><oldname>
  4402.     pop    di
  4403.     pop    si
  4404.     pop    cx
  4405.     pop    bx
  4406.     mov    hidetmp,0
  4407.     ret
  4408. hidewrk    endp
  4409.  
  4410. ; Removes all current \%0..\%9 macros and renames <null><taklev> macros by
  4411. ; removing the first two characters of the names of form <null><taklev>foo.
  4412. ; Used to recover old \%n macros from hidemac and locals from Local.
  4413. unhidemac proc    far
  4414.     push    bx
  4415.     push    cx
  4416.     push    dx
  4417.     push    di                 ; do rename of <null><taklev>foo
  4418. unhide1:mov    di,offset mcctab+1    ; table of macro names, skip count
  4419.     mov    cl,mcctab        ; number of entries
  4420.     xor    ch,ch
  4421.     jcxz    unhide5            ; z = empty table
  4422.     xor    dl,dl            ; dx = macro prefix to examine
  4423.     mov    dh,taklev        ; di => length word, name string
  4424.     mov    dl,hidetmp
  4425.  
  4426. unhide2:cmp    word ptr [di+2],dx    ; starts with <0/1><taklev> prefix?
  4427.     jne    unhide4            ; ne = no
  4428.     mov    bx,di
  4429.     mov    cx,[bx]            ; length of definition
  4430.     sub    cx,2            ; skip prefix bytes
  4431.     push    si
  4432.     mov    si,offset settemp    ; destination work buffer
  4433.     mov    [si],cx         ; new length
  4434.     add    si,2            ; have stored count word
  4435.     add    bx,2+2            ; skip count word and prefix
  4436. unhide3:mov    al,[bx]
  4437.     mov    [si],al            ; copy name to temp array
  4438.     inc    si
  4439.     inc    bx
  4440.     loop    unhide3
  4441.     pop    si
  4442.     mov    bx,di
  4443.     add    bx,[bx]            ; skip macro name
  4444.     add    bx,2            ; and count word
  4445.     mov    cx,[bx]            ; cx is now seg of definition
  4446.     mov    ax,1            ; minimal allocation of one byte
  4447.     call    malloc            ; create dummy def
  4448.     mov    [bx],ax            ; write new dummy def segment
  4449.     call    remtab            ; remove prefixed name, DI is ptr
  4450.     mov    di,offset settemp    ; shortened name
  4451.     call    remtab            ; remove unprefixed macro, DI is ptr
  4452.     mov    bx,offset mcctab    ; mac table
  4453.     mov    dx,offset settemp    ; name string
  4454.     mov    macptr,cx        ; segment of definition
  4455.     call    addtab            ; add to table
  4456.     jmp    unhide1
  4457.  
  4458. unhide4:mov    ax,[di]            ; get length of name
  4459.     add    ax,4            ; plus count and word pointer
  4460.     add    di,ax            ; point to next entry
  4461.     loop    unhide2            ; look at next entry
  4462. unhide5:pop    di
  4463.     pop    dx
  4464.     pop    cx
  4465.     pop    bx
  4466.     ret
  4467. unhidemac endp
  4468.  
  4469. numwd    proc    far            ; worker
  4470.     mov    domath_ptr,offset rdbuf
  4471.     mov    domath_cnt,ax
  4472.     call    domath            ; convert to number in ax
  4473.     jc    num0er            ; c = no number, error
  4474.     cmp    ax,max            ; largest permitted value
  4475.     ja    num0er            ; a = error
  4476.     cmp    ax,min            ; smallest permitted value
  4477.     jb    num0er            ; b = error
  4478.     clc
  4479.     ret                ; return value in ax
  4480.  
  4481. num0er:    mov    dx,numerr        ; comand-specific error message, if any
  4482.     or    dx,dx            ; was any given?
  4483.     jz    num0e1            ; z = no, use generic msg
  4484.     push    ds
  4485.     mov    ax,seg data1        ; where help lives
  4486.     mov    ds,ax
  4487.     mov    ah,prstr
  4488.     int    dos            ; show given error message
  4489.     pop    ds
  4490.     jmp    short num0e2
  4491. num0e1:    mov    dx,offset nummsg1    ; get address of numeric error message
  4492.     push    ds
  4493.     mov    ax,seg data1
  4494.     mov    ds,ax
  4495.     mov    ah,prstr
  4496.     int    dos
  4497.     pop    ds
  4498.     mov    ax,min            ; smallest permitted number
  4499.     call    decout            ; display decimal number in ax
  4500.     mov    ah,prstr
  4501.     push    ds
  4502.     mov    dx,seg nummsg2
  4503.     mov    ds,dx
  4504.     mov    dx,offset nummsg2    ; "and"
  4505.     int    dos
  4506.     pop    ds
  4507.     mov    ax,max            ; largest permitted number
  4508.     call    decout
  4509.     mov    ah,prstr
  4510.     mov    dx,offset crlf
  4511.     int    dos
  4512. num0e2:    stc
  4513.     ret
  4514. numwd    endp
  4515.  
  4516. ; Worker for POP/END and RETURN.
  4517. ; Pop take levels (via takclo) through tails of For/While, back to the
  4518. ; take level of the last DO or prompt command.
  4519. POPLEVEL proc    far
  4520.     cmp    taklev,0        ; in a Take/macro?
  4521.     je    poplevx            ; e = no
  4522.     mov    bx,takadr
  4523.     mov    al,[bx].takinvoke    ; take level of last DO or command
  4524.     mov    ah,[bx].takattr        ; attributes
  4525.     cmp    taklev,al        ; Take level now versus last DO
  4526.     jb    poplevx            ; b = have exited macro already
  4527.     push    ax
  4528.     call    takclos            ; close current Macro/Take
  4529.     pop    ax
  4530.     test    ah,take_while+take_subwhile ; closed While/For/Switch?
  4531.     jz    poplevx            ; z = no
  4532.     mov    bx,takadr
  4533.     test    [bx].takattr,take_while+take_subwhile ; for/while macro?
  4534.     jnz    poplevel        ; nz = yes, exit for/while too
  4535. poplevx:clc
  4536.     ret
  4537. POPLEVEL endp
  4538.  
  4539. FDECLARE    proc    far        ; declare array \&<char @a..z>[size]
  4540.     or    ax,ax            ; null entry?
  4541.     jnz    decl2
  4542.     stc                ; fail
  4543.     ret
  4544. decl2:    cmp    rdbuf[3],'&'        ; syntax checking
  4545.     jne    declf            ; ne = fail
  4546.     cmp    rdbuf[5],'['        ; size bracket?
  4547.     jne    declf            ; ne = no, fail
  4548.     and    rdbuf[4],not 20h    ; to upper case
  4549.     mov    al,rdbuf[4]        ; array name
  4550.     cmp    al,'A'            ; range check
  4551.     jb    declf
  4552.     cmp    al,'Z'
  4553.     ja    declf
  4554.     mov    si,offset rdbuf[6]    ; point at size number
  4555.     xor    ah,ah
  4556.     mov    cx,128            ; limit scan
  4557. decl3:    lodsb
  4558.     cmp    al,']'            ; closing bracket?
  4559.     je    decl4            ; e = yes
  4560.     inc    ah            ; count byte
  4561.     loop    decl3            ; keep looking
  4562.     jmp    declf            ; fail if got here
  4563. decl4:    xor    al,al
  4564.     xchg    ah,al
  4565.     sub    si,ax            ; point at start of number
  4566.     dec    si
  4567.     mov    domath_ptr,si
  4568.     mov    domath_cnt,ax
  4569.     call    domath            ; convert to number in ax
  4570.     jnc    decl5            ; nc = success, value is in DX:AX
  4571.     ret                ; fail
  4572. decl5:    or    dx,dx            ; too large a value?
  4573.     jnz    decl5a            ; nz = yes
  4574.     cmp    ax,32000        ; 32000 max
  4575.     jbe    decl5b            ; be = in range
  4576. decl5a:    mov    dx,offset arraybad    ; say too large
  4577.     mov    ah,prstr
  4578.     int    dos
  4579.     jmp    declf            ; fail
  4580. decl5b:    mov    bl,rdbuf[4]
  4581.     sub    bl,'@'            ; remove bias
  4582.     js    declf            ; s = sign, failure
  4583.     xor    bh,bh            ; preserve bx til end of proc
  4584.     shl    bx,1            ; address words
  4585.     call    decl20            ; call remover
  4586.     cmp    ax,0            ; index of zero to clear the array?
  4587.     je    decl6            ; e = yes, done
  4588.     inc    ax            ; create one more than [value]
  4589.     call    decl10            ; call creator
  4590. decl6:    ret
  4591. declf:    stc                ; failure
  4592.     ret
  4593.  
  4594. decl20    proc    near            ; remove array
  4595.     push    ax            ; save size in ax
  4596.     push    es
  4597.     mov    si,marray[bx]        ; get segment of array's definition
  4598.     or    si,si            ; anything present?
  4599.     jz    decl23            ; no, no need to undefine anything
  4600.     mov    es,si
  4601.     mov    cx,es:[0]        ; get number of elements
  4602.     jcxz    decl23            ; z = none, unlikely
  4603.     xor    si,si            ; count word (number of elements)
  4604. decl21:    add    si,2            ; point to slot holding string seg
  4605.     mov    ax,es:[si]        ; get string seg
  4606.     or    ax,ax            ; null?
  4607.     jz    decl22            ; z = yes, ignore
  4608.     mov    word ptr es:[si],0    ; clear string seg pointer
  4609.     push    es
  4610.     mov    es,ax            ; segment
  4611.     mov    ah,freemem        ; free the memory
  4612.     int    dos
  4613.     pop    es
  4614. decl22:    loop    decl21
  4615.     xor    ax,ax            ; get a zero
  4616.     xchg    ax,marray[bx]        ; clear array seg storage pointer
  4617.     mov    es,ax
  4618.     mov    ah,freemem        ; free storage pointer memory
  4619.     int    dos
  4620. decl23:    pop    es
  4621.     pop    ax
  4622.     clc                ; end removing array
  4623.     ret
  4624. decl20    endp
  4625.  
  4626. decl10    proc    near            ; creator
  4627.     push    ax            ; save ax
  4628.     inc    ax            ; number of elements plus one size int
  4629.     shl    ax,1            ; count bytes for malloc
  4630.     call    malloc            ; get seg of memory to ax
  4631.     pop    cx            ; array size (was in ax)
  4632.     jc    decl12            ; c = failed
  4633.     mov    marray[bx],ax        ; remember storage area
  4634.     push    es
  4635.     push    di
  4636.     mov    es,ax            ; segment of new memory
  4637.     mov    es:[0],cx        ; write size of array as 1st word
  4638.     mov    di,2            ; offset of string seg pointers
  4639.     xor    ax,ax
  4640.     cld
  4641.     rep    stosw            ; clear the array
  4642.     pop    di
  4643.     pop    es
  4644.     clc
  4645. decl12:    ret                ; can return carry set from failure
  4646. decl10    endp
  4647. FDECLARE endp
  4648.  
  4649. ; define contents of array element. Command line is in rdbuf+2 as
  4650. ; \&<char>[index] definition, from dodef. Length of line is in cx.
  4651.  
  4652. defarray proc    far
  4653.     cmp    rdbuf[3],'&'        ; syntax checking
  4654.     jne    defarf            ; ne = fail
  4655.     cmp    rdbuf[5],'['        ; size bracket?
  4656.     jne    defarf            ; ne = no, fail
  4657.     and    rdbuf[4],not 20h    ; to upper case
  4658.     mov    al,rdbuf[4]        ; array name
  4659.     cmp    al,'A'            ; range check
  4660.     jb    defarf
  4661.     cmp    al,'Z'
  4662.     ja    defarf
  4663.     mov    si,offset rdbuf[6]    ; point at size number
  4664.     xor    ah,ah
  4665.     cld
  4666. defar3:    lodsb
  4667.     cmp    al,']'            ; closing bracket?
  4668.     je    defar4            ; e = yes
  4669.     inc    ah            ; count byte
  4670.     loop    defar3            ; keep looking
  4671.     jmp    defarf            ; fail if got here
  4672. defar4:    xor    al,al            ; cx has chars remaining in cmd line
  4673.     xchg    ah,al
  4674.     mov    di,si            ; save di as start of definition space
  4675.     sub    si,ax            ; point at start of number
  4676.     dec    si
  4677.     mov    domath_ptr,si
  4678.     mov    domath_cnt,ax
  4679.     call    domath            ; do string to binary dx:ax
  4680.     jnc    defar5            ; nc = success, value is in DX:AX
  4681.     ret                ; fail
  4682. defar5:    mov    temp,ax            ; save index value
  4683.     mov    bl,rdbuf[4]        ; get array name letter
  4684.     sub    bl,'@'            ; remove bias
  4685.     xor    bh,bh            ; preserve bx til end of proc
  4686.     shl    bx,1            ; address words
  4687.  
  4688. defar6:    call    defar_rem        ; clear current definition, if any
  4689.     inc    di            ; skip space between name and def
  4690.     mov    dx,di            ; for strlen
  4691.     call    strlen            ; length of definition
  4692.     jcxz    defar7            ; z = no definition, done
  4693.     mov    si,marray[bx]        ; segment of array
  4694.     or    si,si            ; if any
  4695.     jz    defar7            ; z = none
  4696.     push    es
  4697.     mov    es,si
  4698.     mov    si,temp            ; array index
  4699.     shl    si,1            ; index words
  4700.     mov    ax,es:[0]        ; get array size
  4701.     shl    ax,1            ; in words
  4702.     cmp    si,ax            ; index versus size
  4703.     ja    defar8            ; a = out of bounds, ignore
  4704.     mov    ax,cx            ; bytes needed
  4705.     add    ax,2+2            ; starts with byte count and elem 0
  4706.     call    malloc            ; get the space
  4707.     jc    defar8            ; c = failed
  4708.     mov    es:[si+2],ax        ; remember segment of string def
  4709.     mov    es,ax            ; string definition seg
  4710.     mov    es:[0],cx        ; length of string
  4711.     mov    si,di            ; start of string text
  4712.     mov    di,2            ; destination
  4713.     cld
  4714.     rep    movsb            ; copy to malloc'd space
  4715.     pop    es
  4716. defar7:    clc                ; success
  4717.     ret
  4718. defar8:    pop    es
  4719. defarf:    mov    kstatus,ksgen        ; general command failure
  4720.     stc                ; failure exit
  4721.     ret
  4722.  
  4723. ; Remove string definition. Enter with BX holding array name index, and
  4724. ; TEMP holding array index.
  4725. defar_rem proc    near            ; remove definition of array element
  4726.     push    ax            ; undefining string within array
  4727.     push    si
  4728.     push    es
  4729.     mov    ax,marray[bx]        ; current array seg
  4730.     or    ax,ax            ; if any
  4731.     jz    defar_rem1        ; z = none
  4732.     mov    si,temp            ; index value
  4733.     shl    si,1            ; index words
  4734.     mov    es,ax
  4735.     mov    ax,es:[0]        ; get array size
  4736.     shl    ax,1            ; in words
  4737.     cmp    si,ax            ; index versus size
  4738.     ja    defar_rem1        ; a = out of bounds, ignore
  4739.     xor    ax,ax            ; get a zero
  4740.     xchg    ax,es:[si+2]        ; get string's segment to ax, clr ref
  4741.     or    ax,ax            ; anything there?
  4742.     jz    defar_rem1        ; z = no
  4743.     mov    es,ax            ; seg to es for DOS
  4744.     mov    ah,freemem        ; free string space
  4745.     int    dos
  4746. defar_rem1:
  4747.     pop    es
  4748.     pop    si
  4749.     pop    ax
  4750.     ret
  4751. defar_rem endp
  4752.  
  4753. defarray endp
  4754.  
  4755. ; Revise string in ES:SI et seq. Expect incoming length to be in CX.
  4756. ; Original string modified to replace bare commas with Carriage Returns.
  4757. ; Top level braces removed, but only if the string begins with an 
  4758. ; opening brace, and hence commas revealed are also converted to CR.
  4759. ; A null is forced at the end of the string.
  4760. ; All registers preserved except CX (returned length).
  4761. docnv    proc    far
  4762.     push    ax
  4763.     push    bx
  4764.     push    dx
  4765.     push    si            ; src domacptr:0,2
  4766.     push    di
  4767.     xor    bx,bx            ; brace count (bl), paren (bh)
  4768.     mov    dl,braceop        ; opening brace (we count them up)
  4769.     mov    dh,bracecl        ; closing brace (we count them down)
  4770.     mov    cx,es:[si]        ; get string length
  4771.     or    cx,cx
  4772.     jnz    docnv1            ; nz = non-empty string
  4773.     pop    di
  4774.     pop    si
  4775.     pop    dx
  4776.     pop    bx
  4777.     pop    ax
  4778.     ret
  4779. docnv1:    add    si,2            ; where text starts
  4780.     mov    di,si            ; si = source
  4781.     cld
  4782.     mov    ah,es:[si]        ; record opening char
  4783. docnv2:    mov    al,es:[si]        ; read a char
  4784.     cmp    al,dl            ; opening brace?
  4785.     jne    docnv3            ; ne = no
  4786.     inc    bl            ; count brace level
  4787.     cmp    bl,1            ; first level?
  4788.     jne    docnv7            ; ne = no, write intact
  4789.     or    bh,bh            ; in parens?
  4790.     jnz    docnv7            ; nz = yes, don't replace
  4791.     cmp    ah,dl            ; started with opening brace?
  4792.     jne    docnv7            ; ne = no, don't replace brace
  4793.     jmp    short docnv8        ; skip opening brace
  4794. docnv3:    cmp    al,dh            ; closing brace?
  4795.     jne    docnv4            ; ne = no
  4796.     dec    bl            ; count down
  4797.     or    bl,bl            ; still within braces?
  4798.     jg    docnv7            ; g = yes, write intact
  4799.     xor    bx,bx            ; found brace match, reset to zero
  4800.     cmp    ah,dl            ; started with opening brace?
  4801.     jne    docnv7            ; ne = no, write brace
  4802.     jmp    short docnv8        ; omit the brace
  4803. docnv4:    cmp    al,'('            ; opening paren?
  4804.     jne    docnv5            ; ne = no
  4805.     inc    bh            ; count paren level
  4806.     jmp    short docnv7
  4807. docnv5:    cmp    al,')'            ; closing paren?
  4808.     jne    docnv6            ; ne = no
  4809.     dec    bh
  4810.     cmp    bh,0            ; below 0?
  4811.     jg    docnv7            ; g = no, still in paren
  4812.     xor    bh,bh            ; in case underrun, reset to zero
  4813.     jmp    docnv7            ; matching paren
  4814. docnv6:    cmp    al,','            ; comma?
  4815.     jne    docnv7            ; ne = no
  4816.     or    bh,bh            ; in paren clause?
  4817.     jnz    docnv7            ; nz = yes, treat comma as literal
  4818.     cmp    bl,0;;1            ; in braced clause?
  4819.     ja    docnv7            ; a = yes, treat comma as literal
  4820.     mov    al,CR            ; replace bare comma with CR
  4821. docnv7:    mov    es:[di],al
  4822.     inc    di            ; next destination byte
  4823. docnv8:    inc    si            ; next input byte
  4824.     loop    docnv2            ; do more
  4825. docnv9:    mov    cx,di            ; ending place + 1
  4826.     pop    di
  4827.     pop    si            ; start of buffer
  4828.     sub    cx,si
  4829.     sub    cx,2            ; minus count word
  4830.     mov    es:[si],cx        ; string length
  4831.     pop    dx
  4832.     pop    bx
  4833.     pop    ax
  4834.     clc
  4835.     ret
  4836. docnv    endp
  4837.  
  4838. code1    ends
  4839.     end
  4840.