home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / msvp98b1.lzh / MSSSHO.ASM < prev    next >
Assembly Source File  |  1993-05-14  |  81KB  |  2,755 lines

  1.     name    msssho
  2. ; File MSSSHO.ASM
  3.     include mssdef.h
  4. ;  Copyright (C) 1985, 1992, Trustees of Columbia University in the 
  5. ;  City of New York.  Permission is granted to any individual or institution
  6. ;  to use this software as long as it is not sold for profit.  This copyright
  7. ;  notice must be retained.  This software may not be included in commercial
  8. ;  products without written permission of Columbia University.
  9. ;
  10. ; Show & Status commands
  11. ; edit history:
  12. ; 6 Sept 1991 version 3.11
  13. ; Last edit 5 Feb 1992
  14.  
  15.     public    shorx, shomac, shcom, shfile, shlog, shpro, shscpt, shserv
  16.     public    shterm, status, statc, stat0, srchkw, srchkb, shmem
  17.     public    partab, destab, seoftab, blktab, dmpname, lsesnam, lpktnam
  18.     public    ltranam, incstb, inactb, rxoffmsg, rxonmsg, lnout, lnouts
  19.     public    shosta, begtim, endtim, fsta, ssta    ; statistics procedures
  20.     public    rtmsg, rppos, stpos, rprpos, sppos, perpos, cxerr, frpos
  21.     public    fmtdsp, ermsg, msgmsg, init, cxmsg, intmsg, kbpr, perpr
  22.     public    winpr, windflag, pktsize, clrfln, oldkbt, oldper
  23.     public  wrpmsg, prttab, pasz, shovar, prnname
  24.  
  25. mcclen    equ    macmax*10
  26.                 ; equates for screen positioning
  27. scrser    equ    0209H        ; place for server state display line
  28. scrfln    equ    0316H        ; place for file name
  29. scrkb    equ    0416H        ; Place for percent transferred
  30. scrper    equ    0516H        ; Place for Kbytes transferred
  31. scrst    equ    0616H        ; Place for status
  32. scrnp    equ    0816H        ; Place for number of packets
  33. scrsz    equ    0916h        ; packet size
  34. scrnrt  equ    0A16H        ; Place for number of retries
  35. screrr  equ    0B16H        ; Place for error msgs
  36. scrmsg    equ    0C16H        ; Last message position
  37. scrsp    equ    0E00H        ; Place for send packet
  38. scrrp    equ    1300H        ; Place for receive packet
  39. scrrpr    equ    1700H        ; Prompt when Kermit ends (does cr/lf)
  40. braceop    equ    7bh        ; opening curly brace
  41. bracecl    equ    7dh        ; closing curly brace
  42.  
  43. data    segment
  44.     extrn    termtb:byte, comptab:byte, portval:word,dtrans:byte,rdbuf:byte
  45.     extrn    trans:byte, curdsk:byte, flags:byte, maxtry:byte, comand:byte
  46.     extrn    spause:byte, taklev:byte, takadr:word, alrhms:byte, bdtab:byte
  47.     extrn    denyflg:word, rxtable:byte, mcctab:byte, script:byte
  48.     extrn    errlev:byte, luser:byte, srvtmo:byte, mccptr:word, thsep:byte
  49.     extrn    scpbuflen:word, setchtab:byte, xfchtab:byte, xftyptab:byte
  50.     extrn    tfilsz:word, diskio:byte, tloghnd:word, dosnum:word
  51.     extrn    templp:byte, windused:byte, numpkt:word, verident:byte
  52.     extrn    decbuf:byte, flotab:byte, warntab:byte, valtab:byte
  53.     extrn    valbuf:byte, xfertab1:byte, xfertab2:byte
  54.  
  55. crlf    db       cr,lf,'$'
  56. eqs    db    ' = $'
  57. spaces    db    '    $'
  58.  
  59. outlin1 db    6 dup (' '),'$'
  60. ;;;    version appears here
  61. outlin2 db    cr,lf,lf
  62.         db      cr,lf,'           File name:'
  63.         db      cr,lf,'  KBytes transferred:'
  64.         db      cr,lf
  65.         db      cr,lf
  66.         db      cr,lf
  67.         db      cr,lf,'   Number of packets:'
  68.     db    cr,lf,'       Packet length:'
  69.         db      cr,lf,'   Number of retries: 0'
  70.         db      cr,lf,'          Last error:'
  71.         db      cr,lf,'        Last message:'
  72.         db      cr,lf,'$'
  73.  
  74.  
  75. permsg    db    cr,' Percent transferred:$'
  76. cxzhlp    db    'X: cancel file, Z: cancel group, E: exit nicely,'
  77.     db    ' C: exit abruptly, Enter: retry$'
  78. erword    db    cr,lf,'Error: $'
  79. msword    db    cr,lf,'Message: $'
  80. rtword    db    cr,lf,'Retry $'
  81. cxzser    db    cr,lf,' Type X to cancel file, Z to cancel group,'
  82.     db    cr,lf,' E to exit nicely, C to quit abruptly,'
  83.     db    cr,lf,' or Enter to retry',cr,lf,'$'
  84. windmsg    db    ' Window slots in use:$'
  85. windmsg2 db    ' of $'
  86. windflag db    0        ; flag to init windows msg, 0=none
  87. oldwind    db    -1        ; last windows in use value
  88. oldper    dw    0        ; old percentage
  89. oldkbt    dw    0        ; old KB transferred
  90. wrpmsg    db    0        ; non-zero if we wrote percent message
  91. fmtdsp    db    0        ; non-zero if formatted display in use
  92. prepksz    dw    0        ; previous packet size
  93. onehun    dw    100
  94. denom    dw    0
  95. temp    dw    0
  96. temp1    dw    0
  97. shmcnt    dw    0
  98. sixteen    dw    16
  99. infms1    db    'Server mode: type Control-C to exit',cr,lf,'$'
  100. infms7    db    'File interrupt',cr,lf,'$'
  101. infms8    db    'File group interrupt',cr,lf,'$'
  102. infms9    db    'User ',5eh,'  interrupt',cr,lf,'$'
  103.  
  104. partab    db    5
  105.     mkeyw    'none (8-bit data) ',PARNON
  106.     mkeyw    'even (7-bit data) ',PAREVN
  107.     mkeyw    'odd (7-bit data) ',PARODD
  108.     mkeyw    'mark (7-bit data) ',PARMRK
  109.     mkeyw    'space (7-bit data) ',PARSPC
  110.  
  111. destab    db    3
  112.     mkeyw    'Disk',1
  113.     mkeyw    'Printer',0
  114.     mkeyw    'Screen',2
  115.  
  116. seoftab    db    2
  117.     mkeyw    'Ctrl-Z',1
  118.     mkeyw    'NoCtrl-Z',0
  119.  
  120. ; What type of block check to use
  121. blktab    db    4
  122.     mkeyw    '1-char-checksum',1
  123.     mkeyw    '2-char-checksum',2
  124.     mkeyw    '3-char-CRC-CCITT',3
  125.     mkeyw    'Blank-free-2','B'-'0'
  126.  
  127. modtab    db    3                ; Mode line status
  128.     mkeyw    'off',0
  129.     mkeyw    'on',1
  130.     mkeyw    'on (owned by host)',2
  131.  
  132. ontab    db    2
  133.     mkeyw    'off',0
  134.     mkeyw    'on',1
  135.  
  136. unkctab db    2            ; unknown character-set disposition
  137.     mkeyw    'keep',0
  138.     mkeyw    'cancel',1
  139.  
  140. logsta    db    8            ; Log Status table
  141.     mkeyw    'off',logoff        ; suspended or no logging
  142.     mkeyw    'Packet',logpkt
  143.     mkeyw    'Session',logses
  144.     mkeyw    'Packet+Session',logpkt+logses
  145.     mkeyw    'Transaction',logtrn
  146.     mkeyw    'Packet+Transaction',logpkt+logtrn
  147.     mkeyw    'Session+Transaction',logses+logtrn
  148.     mkeyw    'Packet+Session+Transaction',logpkt+logses+logtrn
  149.  
  150. dissta    db    6            ; Status of Display mode
  151.     mkeyw    'Quiet, 7-bit',dquiet
  152.     mkeyw    'Regular, 7-bit',dregular
  153.     mkeyw    'Serial, 7-bit',dserial
  154.     mkeyw    'Quiet, 8-bit',dquiet+d8bit
  155.     mkeyw    'Regular, 8-bit',dregular+d8bit
  156.     mkeyw    'Serial, 8-bit',dserial+d8bit
  157.  
  158. endistab db    2            ; Server ENABLE/DISABLE status
  159.     mkeyw    'enabled',0
  160.     mkeyw    'disabled',1
  161.  
  162. inactb    db    2                ; Set Input Timeout Action
  163.     mkeyw    'Proceed',0            ;[jrs]
  164.     mkeyw    'Quit',1            ;[jrs]
  165.  
  166. incstb    db    2                ;[jrs] Set Input Case
  167.     mkeyw    'Ignore',0dfh            ;[jrs]
  168.     mkeyw    'Observe',0ffh            ;[jrs]
  169.  
  170.                 ; Statistics data storage area
  171. fsta    statinfo <>        ; for last operation values
  172. ssta    statinfo <>        ; for session values
  173. sflag    dw    0        ; flag for send (1) or receive (0)
  174.                 ;   80h = begtim started
  175.  
  176. statmsg    db   cr,lf,lf,'                               Last Transfer         '
  177.     db    ' Entire Session'
  178.     db    cr,lf,'   Item                      Sent       Rec''d       '
  179.     db    ' Sent       Rec''d',cr,lf,'$'
  180. fchmsg    db    cr,lf,' File characters:    $'
  181. spmsg    db    cr,lf,' Comms port chars:   $'
  182. pktmsg    db    cr,lf,' Packets:            $'
  183. nakmsg    db    cr,lf,' NAKs:               $'
  184. retmsg    db    cr,lf,' Packet retries:     $'
  185. timemsg    db   cr,lf,lf,' Protocol time, secs:$'
  186. chpsmsg    db    cr,lf,' File characters/sec:$'
  187. spedmsg    db    cr,lf,' Comms port bits/sec:$'
  188. sndmsg    db    'Sent ',0
  189. rcvmsg    db    'Recv ',0
  190. date    db    '00:00:00 00 Jan 1980',0
  191. datelen    equ    $-date-1
  192. atmsg    db    cr,lf,'  at '
  193. atlen    equ    $-atmsg
  194. fasmsg    db    ' as '
  195. faslen    equ    $-fasmsg
  196. fsucmsg    db    ', completed, bytes: ',0
  197. fbadmsg    db    ', failed, bytes: ',0
  198. fintmsg    db    ', interrupted, bytes: ',0
  199. months    db    'JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP'
  200.     db    'OCT','NOV','DEC'
  201.     even
  202. tens    dd    1,10,100,1000,10000,100000,1000000,10000000,100000000
  203.     dd    1000000000
  204. tenslen    equ    ($-tens) / 4    ; number of double words in array tens
  205. lnoutsep db    0        ; non-zero to separate thousands in lnout
  206.                 ; end statistics data area
  207. sixty    dw    60
  208. ten    dw    10
  209.  
  210. logmsg    db    'Kind         Default filename          Status$'
  211. nologmsg db    '(not active)$'
  212. lsesmsg    db    'Session       (Session.log)$'
  213. lpktmsg    db    'Packets       (Packet.log)$'
  214. ltramsg    db    'Transactions  (Transact.log)$'
  215. dmpmsg    db    'Screen Dump, in Connect mode$'
  216. dmpmsg2    db    'Dump screen: $'    ; for general STATUS display
  217. prnmsg    db    'Printer name, in Connect mode: $'
  218. modst    db    'Mode line: $'
  219. locst    db    'Local echo: $'
  220. duphlf    db    'Duplex: half$'
  221. dupful    db    'Duplex: full$'
  222. belon    db    'Ring bell after transfer$'
  223. beloff    db    'No bell after transfer$'
  224. vtemst    db    'Terminal emulation: $'        ; terminal emulator
  225. portst    db    'Communications port: $'
  226. capmsg    db    'Logging: $'
  227. eofmsg    db    'EOF mode: $'
  228. flost    db    'No flow control used$'
  229. floxmsg    db    'Flow control: xon/xoff $'
  230. flost1    db    'Flow control: $'
  231. handst    db    'Handshake used: $'
  232. destst    db    'Destination: $'
  233. xtypmsg    db    'File Type: $'
  234. xchmsg    db    'Transfer char-set: $'
  235. xchmsg1    db    'Transfer locking-shift: $'
  236. xchmsg2    db    'Transfer translation: $'
  237. chmsg    db    'File char set: $'
  238. unkmsg    db    'Unknown-char-set: $'
  239. diskst    db    'Dir: $'
  240. blokst    db    'Block check used: $'
  241. sqcst    db    'Send control char prefix: $'
  242. rqcst    db    'Receive control char prefix: $'
  243. debon    db    'Debug: $'
  244. flwon    db    'Collision (file name): $'
  245. parmsg    db    'Parity: $'
  246. abfdst    db    'Incomplete file: discard$'
  247. abfkst    db    'Incomplete file: keep$'
  248. sndmsg1    db    'Send Delay: $'
  249. sndmsg2    db    ' sec, Pause: $'
  250. sndmsg3    db    ' ms$'
  251. msohst    db    'Start-of-Packet char S: ',5eh,'$'
  252. meolst    db    'End-of-Packet char   S: ',5eh,'$'
  253. msrec    db    '  R: ',5eh,'$'
  254. msrecv    db    '  R: $'
  255. tmost    db    'Timeout (seconds)    S: $'
  256. stimst    db    'Send timeout (seconds): $'
  257. rtimst    db    'Receive timeout (seconds): $'
  258. spakst    db    'Send packet size (maximum): $'
  259. rpakst    db    'Receive packet size (maximum): $'
  260. spakst1    db    'Send packet size (current): $'
  261. rpakst1    db    'Receive packet size (current): $'
  262. snpdst    db    'Number of padding chars S: $'
  263. spadst    db    'Padding char S: ',5eh,'$'
  264. retrymsg db    'Retry send/receive packet limit: $'
  265. swinst    db    'Sliding window slots (max): $'
  266. dispst    db    'Display: $'
  267. timmsg    db    'Timer: $'
  268. srvmsg    db    'Timeout (sec) waiting for a transaction: $'
  269. dblmsg    db    'Send double-char: $'
  270. ignmsg    db    'Receive ignore-char: $'
  271. escmes    db    'Escape character: $'
  272. scpmsg    db    'Script commands Echo, If, Input, Output, Pause, Reinput,'
  273.     db    ' Transmit, Wait$'
  274. sechmsg    db    'Input echoing: $'
  275. scasmsg    db    'Case sensitivity: $'
  276. stmo1msg db    'Timeout (seconds): $'
  277. stmo2msg db    'Timeout-action: $'
  278. sxfilmsg db    'Transmit fill-empty-line: $'
  279. sxlfmsg db    'Transmit line-feeds-sent: $'
  280. sxpmtmsg db    'Transmit prompt character: $'
  281. sxpaumsg db    'Transmit pause (millisec): $'
  282. stbufmsg db    'INPUT-buffer-length: $'
  283. stinbmsg db    'INPUT-BUFFER follows:',cr,lf,'$'
  284. takon    db    'Take-echo: $'
  285. atton    db    'Attributes packets: $'
  286. sachmsg    db    '  Character-set: $'
  287. sadtmsg    db    '  Date-Time: $'
  288. salnmsg    db    '  Length: $'
  289. satymsg    db    '  Type: $'
  290. baudrt    db    'Speed: $'
  291. unrec    db    'unknown$'
  292. kbdmsg    db    'Keyboard translation: $'
  293. stcntmsg db    'Take/Macro COUNT: $'
  294. stargmsg db    'Take/Macro ARGC: $'
  295. nonemsg    db    'not active$'
  296. sterlmsg db    'Errorlevel: $'
  297. stalrmsg db    'Alarm time: $'
  298. lusrmsg    db    'Login Username: $'
  299. servmsg    db    'Server commands available to remote user: $'
  300. scwdmsg    db    'CD/CWD: $'
  301. sdelmsg    db    'DELETE: $'
  302. sdirmsg    db    'DIR:    $'
  303. sfinmsg    db    'FINISH: $'
  304. sgetmsg    db    'GET:    $'
  305. shstmsg    db    'HOST:   $'
  306. skermsg    db    'KERMIT: $'
  307. slogmsg    db    'LOGIN:  $'
  308. ssndmsg    db    'MESSAGE:$'
  309. sprtmsg    db    'PRINT:  $'
  310. sspcmsg    db    'SPACE:  $'
  311. stypmsg    db    'TYPE:   $'
  312. stekmsg    db    'Tek4010: $'
  313. nonmsg    db    'none$'
  314. onmsg    db    'on'
  315. offmsg    db    'off'
  316. moremsg    db    cr,lf,'-- More -- press space for more,'
  317.     db    ' q or Control-C to quit. $'
  318. rxoffmsg db    cr,lf,'  Input Translation is off$'
  319. rxonmsg    db    cr,lf,'  Input Translation is on$'
  320.  
  321. shormsg    db    cr,lf,'  Translation table of received byte codes while'
  322.     db    ' in CONNECT mode -'
  323.     db    cr,lf,'  Format: [received byte (decimal) -> local byte'
  324.     db    ' (decimal)]',cr,lf,'$'
  325. shopm1    db    ' [\$'            ; Show Translation material
  326. shopm2    db    ' -> \$'
  327. shopm3    db    '] $'
  328. shmmsg    db    ' name of macro, or press ENTER to see all$'
  329. shvmsg    db    ' name of \v(name) variable, or press ENTER to see all$'
  330. shom9m1    db    cr,lf,' Free space (bytes) for names: $'
  331. shom9m3    db    cr,lf,' No macro(s)$'
  332. shom9m4    db    '<cr>$'
  333. memmsg1    db    cr,lf,' DOS free memory (bytes):$'
  334. memmsg2    db    cr,lf,' Total free bytes: $'
  335. varstng    db    cr,lf,' \v($'
  336.  
  337. prterr    db    '?Unrecognized value$'
  338. lpktnam    db    'Packet.log',54 dup (0)    ; default packet log filename
  339. lsesnam    db    'Session.log',54 dup (0); default capture/session filename
  340. ltranam    db    'Transact.log',52 dup (0); default transaction log filename
  341. dmpname    db    'Kermit.scn',54 dup (0)    ; file name for screen dumps
  342. prnname    db    'PRN',61 dup (0)    ; file name for printer
  343.  
  344.     even
  345. stent    struc            ; structure for status information table sttab
  346. sttyp    dw    ?        ; type (actually routine to call)
  347. msg    dw    ?        ; message to print
  348. val2    dw    ?        ; needed value: another message, or tbl addr
  349. tstcel    dw    ?        ; address of cell to test, in data segment
  350. basval    dw    0        ; base value, if non-zero
  351. stent    ends
  352.  
  353. sttab    stent    <baudprt>                ; STATUS
  354.     stent    <srchkww,vtemst,termtb,flags.vtflg>    ; terminal emulator
  355.     stent    <srchkw,portst,comptab,flags.comflg>
  356.     stent    <srchkw,modst,modtab,flags.modflg>
  357.     stent    <srchkw,parmsg,partab,parflg,portval>
  358.     stent    <stlnum,spakst,,dtrans.slong>
  359.     stent    <onoff,locst,,ecoflg,portval>
  360.     stent    <stlnum,rpakst,,dtrans.rlong>
  361.     stent    <srchkw,flost1,flotab,floflg,portval>
  362.     stent    <prsar,msohst,msrec,trans.ssoh,trans.rsoh>
  363.     stent    <prhnd>
  364.     stent    <prsar,meolst,msrec,trans.seol,trans.reol>
  365.     stent    <msg2,dupful,duphlf,duplex,portval>
  366.     stent    <prsarv,tmost,msrecv,dtrans.stime,trans.rtime>
  367.     stent    <drnum,diskst,,curdsk>
  368.     stent    <stnum,retrymsg,,maxtry>
  369.     stent    <srchkw,flwon,warntab,flags.flwflg>
  370.     stent    <srchkw,blokst,blktab,dtrans.chklen>
  371.     stent    <srchkw,destst,destab,flags.destflg>
  372.     stent    <srchkw,capmsg,logsta,flags.capflg>
  373.     stent    <msg2,abfkst,abfdst,flags.abfflg>
  374.     stent    <srchkw,debon,logsta,flags.debug>
  375.     stent    <srchkw,dispst,dissta,flags.remflg>
  376.     stent    <onoff,timmsg,,flags.timflg>
  377.     stent    <onechr,escmes,,trans.escchr>
  378.     stent    <srchkw,kbdmsg,ontab,flags.xltkbd>
  379.     stent    <vtstat>
  380.     dw    0                ; end of table
  381.  
  382. stcom    stent    <srchkw,portst,comptab,flags.comflg>    ; SHOW COMMS
  383.     stent    <baudprt>
  384.     stent    <onoff,locst,,ecoflg,portval>
  385.     stent    <srchkw,parmsg,partab,parflg,portval>
  386.     stent    <prhnd>
  387.     stent    <srchkw,flost1,flotab,floflg,portval>
  388.     stent    <msg2,dupful,duphlf,duplex,portval>
  389.     stent    <srchkw,dispst,dissta,flags.remflg>
  390.     stent    <srchkw,debon,logsta,flags.debug>
  391.     dw    0
  392.  
  393. stfile    stent    <drnum,diskst,,curdsk>            ; SHOW FILE
  394.     stent    <msg2,abfkst,abfdst,flags.abfflg>
  395.     stent    <srchkw,destst,destab,flags.destflg>
  396.     stent    <srchkw,flwon,warntab,flags.flwflg>
  397.     stent    <srchkw,eofmsg,seoftab,flags.eofcz>
  398.     stent    <srchkww,chmsg,setchtab,flags.chrset>
  399.     stent    <srchkw,xtypmsg,xftyptab,dtrans.xtype>
  400.     stent    <srchkw,xchmsg,xfchtab,dtrans.xchset>
  401.     stent    <msg2,beloff,belon,flags.belflg>
  402.     stent    <srchkw,xchmsg2,xfertab2,dtrans.xchri>
  403.     stent    <stmsg,atton>
  404.     stent    <srchkw,xchmsg1,xfertab1,dtrans.lshift>
  405.     stent    <srchkb,sachmsg,ontab,attchr,flags.attflg>
  406.     stent    <srchkw,unkmsg,unkctab,flags.unkchs>
  407.     stent    <srchkb,sadtmsg,ontab,attdate,flags.attflg>
  408.     stent    <stmsg,spaces>
  409.     stent    <srchkb,salnmsg,ontab,attlen,flags.attflg>
  410.     stent    <stmsg,spaces>
  411.     stent    <srchkb,satymsg,ontab,atttype,flags.attflg>
  412.     dw    0
  413.  
  414. stlog    stent    <stmsg,logmsg>                ; SHOW LOG
  415.     stent    <stmsg,lpktmsg>
  416.     stent    <msg2b,nologmsg,lpktnam,logpkt,flags.capflg>
  417.     stent    <stmsg,lsesmsg>
  418.     stent    <msg2b,nologmsg,lsesnam,logses,flags.capflg>
  419.     stent    <stmsg,ltramsg>
  420.     stent    <msg2b,nologmsg,ltranam,logtrn,flags.capflg>
  421.     stent    <stmsg,dmpmsg>
  422.     stent    <stmsg,dmpname>
  423.     stent    <stmsg,prnmsg>
  424.     stent    <stmsg,prnname>
  425.     dw    0
  426.  
  427. stpro    stent    <stlnum,spakst,,dtrans.slong>        ; SHOW PROTOCOL
  428.     stent    <stlnum,rpakst,,dtrans.rlong>
  429.     stent    <stlnum,spakst1,,trans.slong>
  430.     stent    <stlnum,rpakst1,,trans.rlong>
  431.     stent    <stnum,stimst,,dtrans.stime>
  432.     stent    <stnum,rtimst,,trans.rtime>
  433.     stent    <onechr,sqcst,,dtrans.squote>
  434.     stent    <onechr,rqcst,,trans.rquote>
  435.     stent    <prsar,msohst,msrec,trans.ssoh,trans.rsoh>
  436.     stent    <prsarv,snpdst,msrecv,dtrans.spad,trans.rpad>
  437.     stent    <prsar,meolst,msrec,trans.seol,trans.reol>
  438.     stent    <prsar,spadst,msrec,dtrans.spadch,trans.rpadch>
  439.     stent    <onechr,dblmsg,,dtrans.sdbl>
  440.     stent    <onechr,ignmsg,,dtrans.rign>
  441.     stent    <prsnd,sndmsg1>
  442.     stent    <srchkw,blokst,blktab,dtrans.chklen>
  443.     stent    <stnum,retrymsg,,maxtry>
  444.     stent    <stnum,swinst,,dtrans.windo>
  445.     stent    <onoff,timmsg,,flags.timflg>
  446.     stent    <prhnd>
  447.     stent    <srchkw,debon,logsta,flags.debug>
  448.     stent    <srchkw,capmsg,logsta,flags.capflg>
  449.     stent    <srchkw,xtypmsg,xftyptab,dtrans.xtype>
  450.     stent    <srchkww,chmsg,setchtab,flags.chrset>
  451.     stent    <stmsg,atton>
  452.     stent    <srchkw,xchmsg,xfchtab,dtrans.xchset>
  453.     stent    <srchkb,sachmsg,ontab,attchr,flags.attflg>
  454.     stent    <srchkw,xchmsg2,xfertab2,dtrans.xchri>
  455.     stent    <srchkb,sadtmsg,ontab,attdate,flags.attflg>
  456.     stent    <srchkw,xchmsg1,xfertab1,dtrans.lshift>
  457.     stent    <srchkb,salnmsg,ontab,attlen,flags.attflg>
  458.     stent    <stmsg,spaces>
  459.     stent    <srchkb,satymsg,ontab,atttype,flags.attflg>
  460.     dw    0
  461.  
  462. stscpt    stent    <stmsg,scpmsg>                ; SHOW SCRIPT
  463.     stent    <onoff,sechmsg,,script.inecho>
  464.     stent    <srchkw,scasmsg,incstb,script.incasv>
  465.     stent    <stlnum,stmo1msg,,script.indfto>
  466.     stent    <srchkw,stmo2msg,inactb,script.inactv>
  467.     stent    <stalr,stalrmsg>
  468.     stent    <stlnum,stbufmsg,,scpbuflen>
  469.     stent    <stnum,sterlmsg,,errlev>
  470.     stent    <prfil>
  471.     stent    <onoff,sxlfmsg,,script.xmitlf>
  472.     stent    <stlnum,sxpaumsg,,script.xmitpause>
  473.     stent    <onechr,sxpmtmsg,,script.xmitpmt>
  474.     stent    <stcnt,stcntmsg>
  475.     stent    <srchkw,takon,ontab,flags.takflg>
  476.     stent    <starg,stargmsg>
  477.     stent    <stmsg,stinbmsg>
  478.     stent    <stinbuf>
  479.     dw    0
  480.  
  481. stserv    stent    <pasz,lusrmsg,offset luser>        ; SHOW SERVER
  482.     stent    <stmsg,servmsg>
  483.     stent    <srchkb,scwdmsg,endistab,cwdflg,denyflg>
  484.     stent    <srchkb,skermsg,endistab,kerflg,denyflg>
  485.     stent    <srchkb,sdelmsg,endistab,delflg,denyflg>
  486.     stent    <srchkb,slogmsg,endistab,pasflg,denyflg>
  487.     stent    <srchkb,sdirmsg,endistab,dirflg,denyflg>
  488.     stent    <srchkb,ssndmsg,endistab,sndflg,denyflg>
  489.     stent    <srchkb,sfinmsg,endistab,finflg,denyflg>
  490.     stent    <srchkb,sprtmsg,endistab,prtflg,denyflg>
  491.     stent    <srchkb,sgetmsg,endistab,getsflg,denyflg>
  492.     stent    <srchkb,sspcmsg,endistab,spcflg,denyflg>
  493.     stent    <srchkb,shstmsg,endistab,hostflg,denyflg>
  494.     stent    <srchkb,stypmsg,endistab,typflg,denyflg>
  495.     dw    0
  496. stserv2    stent    <stnum,srvmsg,,srvtmo>
  497.     dw    0
  498.  
  499. stterm    stent    <srchkw,vtemst,termtb,flags.vtflg>    ; SHOW TERMINAL
  500.     stent    <srchkw,dispst,dissta,flags.remflg>
  501.     stent    <srchkb,stekmsg,endistab,tekxflg,denyflg>
  502.     stent    <onechr,escmes,,trans.escchr>
  503.     stent    <srchkw,modst,modtab,flags.modflg>
  504.     stent    <srchkw,kbdmsg,ontab,flags.xltkbd>
  505.     stent    <vtstat>
  506.     dw    0
  507.  
  508. shorxk    stent    <srchkw,kbdmsg,ontab,flags.xltkbd>
  509.     stent    <stmsg,spaces>
  510.     dw    0
  511.  
  512. data    ends
  513.  
  514. code    segment
  515.     extrn    comnd:near, decout:near, locate:near, prtscr:near, strlen:near
  516.     extrn    getbaud:near, vtstat:near, shomodem:near, nvaltoa:near
  517.     extrn    cmblnk:near, prtasz:near, putmod:near, clrmod:near
  518.     extrn    poscur:near, clearl:near, nout:near, dodec:near, buflog:near
  519.     extrn    dec2di:near
  520.  
  521.     assume    cs:code, ds:data, es:nothing
  522.  
  523. fstrlen    proc    far        ; FAR callable versions of items in seg code
  524.     call    strlen        ;  for calling from code segment code1 below
  525.     ret
  526. fstrlen    endp
  527. fdec2di    proc    far
  528.     call    dec2di
  529.     ret
  530. fdec2di    endp
  531. fprtscr    proc    far
  532.     call    prtscr
  533.     ret
  534. fprtscr    endp
  535. fprtasz    proc    far
  536.     call    prtasz
  537.     ret
  538. fprtasz    endp
  539. flnout    proc    far
  540.     call    lnout
  541.     ret
  542. flnout    endp
  543. flnouts    proc    far
  544.     call    lnouts
  545.     ret
  546. flnouts    endp
  547. fnvaltoa proc    far
  548.     call    nvaltoa
  549.     ret
  550. fnvaltoa endp
  551. ; Display asciiz message pointed to by DS:DX on Last error line
  552. ERMSG    PROC    NEAR
  553.     test    flags.remflg,dquiet    ; quiet screen?
  554.     jnz    ermsgx            ; nz = yes
  555.     push    si            ; position cursor to Last Error line
  556.     push    dx            ; save preexisting message pointer
  557.     test    flags.remflg,dserial    ; serial mode display?
  558.     jnz    erpo1            ; nz = yes
  559.     cmp    fmtdsp,0        ; formatted display?
  560.     jne    erpo2            ; ne = yes
  561. erpo1:    mov    ah,prstr
  562.     mov    dx,offset erword    ; put out word Error:
  563.     int    dos
  564.     jmp    short erpo3
  565. erpo2:    mov    dx,screrr
  566.     call    poscur
  567.     call    clearl            ; clear the line
  568. erpo3:    pop    dx            ; restore old pointer
  569.     mov    si,dx            ; string pointer
  570.     mov    cx,10            ; try ten items
  571.     cld
  572. ermsg1:    lodsb
  573.     cmp    al,' '            ; strip these leading spaces
  574.     loope    ermsg1
  575.     dec    si            ; backup to non-space
  576.     push    dx            ; preserve caller's dx
  577.     mov    dx,si
  578.     call    prtasz            ; display asciiz message
  579.     pop    dx
  580.     pop    si
  581. ermsgx:    ret
  582. ERMSG    ENDP
  583.  
  584. ; Decode and display Message packet pointed to by SI.
  585. MSGMSG    PROC    NEAR
  586.     test    flags.remflg,dquiet    ; quiet screen?
  587.     jnz    msgmsgx            ; nz = yes
  588.     cmp    [si].datlen,0        ; anything present?
  589.     je    msgmsgx            ; e = no
  590.     test    flags.remflg,dserial    ; serial mode display?
  591.     jnz    msgms1            ; nz = yes
  592.     cmp    fmtdsp,0        ; formatted display?
  593.     jne    msgms2            ; ne = yes
  594.     cmp    flags.xflg,0        ; packet header seen?
  595.     je    msgms2            ; e = no
  596. msgms1:    mov    ah,prstr
  597.     mov    dx,offset msword    ; put out word Message:
  598.     int    dos
  599.     jmp    short msgms3        ; display the message
  600. msgms2:    push    si
  601.     mov    dx,scrmsg        ; Last message line
  602.     call    poscur
  603.     call    clearl            ; clear the line
  604.     pop    si
  605. msgms3:    call    dodec            ; decode to decbuf, SI is pktinfo ptr
  606.     mov    dx,offset decbuf    ; final error message string, asciiz
  607.     call    prtasz            ; display asciiz message
  608. msgmsgx:ret
  609. MSGMSG    ENDP
  610.  
  611. ; Show number of retries message
  612.  
  613. RTMSG    PROC     NEAR
  614.     test    flags.remflg,dquiet    ; quiet display mode?
  615.     jnz    rtmsx            ; nz = yes
  616.     test    flags.remflg,dserver    ; in server mode?
  617.     jnz    rtms0            ; nz = yes
  618.     cmp    flags.xflg,0        ; receiving to screen?
  619.     jne    rtmsx            ; ne = yes
  620.     cmp    fmtdsp,0        ; formatted display?
  621.     je    rtms1            ; e = no, do as normal
  622. rtms0:    test    flags.remflg,dserial    ; serial mode display?
  623.     jnz    rtms1            ; nz = yes
  624.     push    ax
  625.     push    dx
  626.     push    si
  627.     mov    dx,scrnrt
  628.     call    poscur
  629.     call    clearl
  630.     pop    si
  631.     jmp    short rtms3
  632. rtms1:    push    ax
  633.     push    dx
  634.     mov    dx,offset rtword    ; display word Retry
  635.     mov    ah,prstr
  636.     int    dos
  637. rtms3:    mov    ax,fsta.pretry        ; number of retries
  638.     call    decout            ; write the number of group retries
  639.     pop    dx
  640.     pop    ax
  641. rtmsx:    ret
  642. RTMSG    ENDP
  643.  
  644. ; Reassure user that we acknowledge his ^X/^Z
  645.  
  646. INTMSG    PROC    NEAR
  647.     cmp    flags.cxzflg,0        ; anything there?
  648.     je    int1            ; e = no
  649.     test    flags.remflg,dserver    ; server mode?
  650.     jnz    int4            ; nz = yes
  651.     cmp    flags.xflg,0        ; writing to screen?
  652.     jne    int1            ; ne = yes, nothing to do
  653. int4:    test    flags.remflg,dquiet    ; quiet screen?
  654.     jnz    int1            ; yes, suppress msg
  655.     test    flags.remflg,dserial    ; serial mode display?
  656.     jz    int2            ; z = no
  657.     cmp    fmtdsp,0        ; formatted screen?
  658.     jne    int2            ; ne = yes
  659.     mov    dx,offset crlf        ; output initial cr/lf
  660.     mov    ah,prstr
  661.     int    dos
  662.     jmp    short int3        ; display the message
  663. int2:    mov    dx,scrmsg        ; last message position
  664.     call    poscur
  665.     call    clearl
  666. int3:    mov    dx,offset infms7    ; File interrupted
  667.     cmp    flags.cxzflg,'X'    ; File interrupt? 
  668.     je    int0            ; e = yes
  669.     mov    dx,offset infms8    ; File group interrupted
  670.     cmp    flags.cxzflg,'Z'    ; correct?
  671.     je    int0            ; e = yes
  672.     mov    dl,flags.cxzflg        ; say Control ^letter interrupt
  673.     mov    infms9+6,dl        ; store interrupt code letter
  674.     mov    dx,offset infms9
  675. int0:   mov    ah,prstr
  676.         int    dos
  677. int1:    ret
  678. INTMSG    ENDP
  679.  
  680. ;  Clear Last error and Last message lines
  681. cxerr:    mov    temp,0            ; say last error line
  682.     jmp    short cxcomm        ; do common code
  683.  
  684. CXMSG    PROC    NEAR
  685.     mov    temp,1            ; say last message line
  686.  
  687. cxcomm:    test    flags.remflg,dserver    ; server mode?
  688.     jnz    cxm1            ; nz = yes
  689.     cmp    flags.xflg,0        ; Writing to screen?
  690.     jne    cxm0            ; ne = yes
  691. cxm1:    cmp    fmtdsp,0        ; formatted display?
  692.     je    cxm0            ; e = no
  693.     push    dx
  694.     push     si
  695.     mov    dx,screrr        ; Last Error postion
  696.     cmp    temp,0            ; do last error line?
  697.     je    cxm2            ; e = yes
  698.     mov    dx,scrmsg        ; Last Message position
  699. cxm2:    call    poscur
  700.     call    clearl
  701.     pop    si
  702.     pop    dx
  703. cxm0:    ret
  704. CXMSG    ENDP
  705.  
  706. ;  Clear out the old filename on the screen. 
  707.  
  708. CLRFLN    PROC    NEAR
  709.     test    flags.remflg,dquiet     ; quiet display?
  710.     jnz    clrflnx            ; nz = yes
  711.     test    flags.remflg,dserial    ; serial display mode?
  712.     jnz    clrfln1            ; nz = yes, use just cr/lf
  713.     cmp    fmtdsp,0        ; formatted display?
  714.     je    clrfln1            ; e = no
  715.     mov    dx,scrfln
  716.     call    poscur
  717.     call    clearl            ; clear to end of line
  718.     ret
  719. clrfln1:push    ax            ; for serial display, does cr/lf
  720.     mov    ah,prstr
  721.     mov    dx,offset crlf
  722.     int    dos
  723.     pop    ax
  724. clrflnx:ret
  725. CLRFLN    ENDP
  726.  
  727.             ; display packet quantity and size, SI has pkt ptr
  728. PKTSIZE    PROC    NEAR
  729.     push    ax
  730.     push    dx
  731.     push    si
  732.     cmp    fmtdsp,0        ; formatted display?
  733.     je    pktsiz2            ; e = no, no display
  734.     mov    ax,[si].datlen        ; packet size (data part)
  735.     cmp    trans.chklen,'B'-'0'    ; this special case?
  736.     jne    pktsiz4            ; ne = no
  737.     add    al,2            ; special case is two byte chksum
  738.     jmp    short pktsiz5
  739. pktsiz4:add    al,trans.chklen        ; plus checksum
  740. pktsiz5:adc    ah,0
  741.     cmp    ax,prepksz        ; same as previous packet?
  742.     je    pktsiz2            ; e = yes, skip display of size
  743.     push    ax
  744.     mov    dx,scrsz        ; position cursor
  745.     call    poscur
  746.     call    clearl            ; clear to end of line
  747.     pop    ax
  748.     mov    prepksz,ax        ; remember new value
  749.     add    ax,3            ; plus LEN, SEQ, TYPE
  750.     cmp    ax,94            ; larger than Regular?
  751.     jbe    pktsiz1            ; be = no
  752.     add    ax,3            ; add Long Packet len and chksum
  753. pktsiz1:call    decout            ; show packet length
  754.                     ; number of packets part
  755. pktsiz2:test    flags.remflg,dquiet    ; quiet screen?
  756.     jnz    pktsiz3            ; nz = yes
  757.     call    nppos            ; number of packets sent
  758.     mov    ax,numpkt        ; number of packets
  759.     call    nout            ; write the packet number
  760. pktsiz3:pop    si
  761.     pop    dx
  762.     pop    ax
  763.     ret
  764. PKTSIZE    ENDP
  765.  
  766. ; some random screen positioning functions
  767. kbpos:    mov    dx,scrkb        ; KBytes transferred
  768.     cmp    fmtdsp,0        ; formatted display?
  769.     jne    setup2            ; ne = yes
  770.     ret                ; else ignore postioning request
  771. perpos:    mov    dx,scrper        ; Percent transferred
  772.     cmp    fmtdsp,0        ; formatted display?
  773.     jne    setup2            ; ne = yes
  774.     ret                ; else ignore postioning request
  775. frpos:    mov    dx,scrmsg        ; say renamed file
  776.     jmp    short setup2
  777. stpos:    mov    dx,scrst        ; status of file transfer
  778.     jmp    short setup2
  779. nppos:    mov    dx,scrnp        ; Number of packets sent
  780.     cmp    fmtdsp,0        ; formatted display?
  781.     jne    setup2            ; ne = yes
  782.     ret
  783. rprpos:    test    flags.remflg,dserial+dquiet ; reprompt position
  784.     jnz    rprpos1            ; nz = no mode line for these
  785.     cmp    fmtdsp,0        ; formatted display?
  786.     je    rprpos1            ; e = no, so no mode line
  787.     call    clrmod            ; clear mode line
  788. rprpos1:mov    dx,scrrpr        ; Reprompt position
  789.     call    setup2            ; position cursor
  790.     mov    fmtdsp,0        ; turn off formatted display flag
  791.     ret
  792. sppos:    mov    dx,scrsp        ; Debug Send packet location
  793.     jmp    short setup1
  794. rppos:    mov    dx,scrrp        ; Debug Receive packet location
  795.     jmp    short setup1
  796.                 ; common service routines for positioning
  797. setup1:    test    flags.remflg,dquiet+dserial; quiet or serial display mode?
  798.     jnz    setupa            ; nz = yes
  799.     cmp    fmtdsp,0        ; non-formatted display?
  800.     je    setupa            ; e = yes
  801.     jmp    poscur
  802. setup2:    test    flags.remflg,dquiet+dserial; quiet or serial display mode?
  803.     jnz    setupa            ; nz = yes
  804.     cmp    fmtdsp,0        ; non-formatted display?
  805.     je    setupa            ; e = yes
  806.     call    poscur            ; no
  807.     jmp    clearl
  808. setupa: test    flags.remflg,dquiet    ; quiet mode?
  809.     jnz    setupx            ; nz = yes, do nothing
  810.     push    ax            ; display cr/lf and return
  811.     push    dx
  812.     mov    dx,offset crlf
  813.     mov    ah,prstr
  814.     int    dos
  815.     pop    dx
  816.     pop    ax
  817. setupx:    ret
  818.  
  819. ; Initialize formatted screen
  820.  
  821. INIT    PROC    NEAR
  822.     mov    windflag,0        ; init windows in use display flag
  823.     test    flags.remflg,dquiet    ; quiet display mode?
  824.     jnz    init4            ; nz = yes
  825.     test    flags.remflg,dserver    ; server mode?
  826.     jnz    init1            ; nz = yes
  827.     cmp    flags.xflg,0        ; destination is screen
  828.     jne    init4            ; ne = yes
  829. init1:    test    flags.remflg,dserial    ; serial mode display?
  830.     jnz    init3            ; nz = yes
  831.     call    cmblnk            ; clear the screen
  832.     mov    dx,offset cxzhlp
  833.     call    putmod            ; write mode line
  834.     mov    fmtdsp,1        ; say doing formatted display
  835.     test    flags.remflg,dserver    ; server mode?
  836.     jz    init2            ; z = no
  837.     mov    dx,scrser        ; move cursor to top of screen
  838.     call    poscur
  839.     mov    ah,prstr
  840.     mov    dx,offset infms1    ; say now in server mode
  841.     int    dos
  842. init2:    call    locate
  843.     mov    ah,prstr        ; put statistics headers on the screen
  844.     mov    dx,offset outlin1
  845.     int    dos
  846.     mov    dx,offset verident
  847.     int    dos
  848.     mov    dx,offset outlin2
  849.     int    dos
  850.     mov    wrpmsg,0        ; haven't printed the messsage yet
  851.     mov    prepksz,0        ; set previous packet size to zero
  852.     ret
  853. init3:    mov    ah,prstr
  854.     mov    dx,offset cxzser    ; status line as a text string
  855.     int    dos
  856. init4:    mov    wrpmsg,1        ; suppress display of percentage msg
  857.     mov    fmtdsp,0        ; say doing unformatted display
  858.     ret
  859. INIT    ENDP
  860.  
  861. ; show number of Kilobytes transferred
  862. ; modifies ax
  863. kbpr    proc    near
  864.     test    flags.remflg,dquiet    ; quiet display mode?
  865.     jnz    kbpr1            ; nz = yes, no printing
  866.     push    bx
  867.     mov    ax,tfilsz        ; low order word
  868.     mov    bx,tfilsz+2        ; high order word
  869.     add    ax,512            ; round up, add half the denominator
  870.     adc    bx,0
  871.     rcr    bx,1            ; divide double word by 1024,
  872.     rcr    ax,1            ; by dword shift right 10
  873.     rcr    bx,1
  874.     rcr    ax,1
  875.     mov    al,ah
  876.     mov    ah,bl            ; ax has the result
  877.     pop    bx
  878.     cmp    ax,oldkbt        ; is it the same?
  879.     je    kbpr1            ; yes, skip printing
  880.     mov    oldkbt,ax        ; save new # of kb
  881.     push    ax
  882.     call    kbpos            ; postion the cursor
  883.     pop    ax
  884.     call    decout            ; print number of KBytes transferred
  885. kbpr1:    ret
  886. kbpr    endp    
  887.  
  888. ; show percent transferred
  889. ; modifies ax
  890. perpr    proc    near
  891.     test    flags.remflg,dquiet    ; quiet display mode?
  892.     jz    perpr1            ; z = no. allow printing
  893.     ret                ; skip printing in remote mode
  894. perpr1:    cmp    diskio.sizehi,0        ; high word of original file size > 0 ?
  895.     jne    perpr3            ; ne = yes, use big file code
  896.     cmp    diskio.sizelo,0        ; anything here at all?
  897.     jne    perpr2            ; ne = yes, use small file code
  898.     ret                ; otherwise, quit now
  899. perpr2:    push    cx            ; case for files < 64 Kb
  900.     push    dx
  901.     mov    ax,diskio.sizelo    ; original size (low word)
  902.     mov    denom,ax
  903.     mov    dx,tfilsz+2        ;transferred size times 256 in [dx,ax]
  904.     mov    ax,tfilsz
  905.     mov    dh,dl            ; whole value multiplied by 256
  906.     mov    dl,ah
  907.     mov    ah,al
  908.     xor    al,al
  909.     mov    cx,denom        ; round up, add half the denominator
  910.     shr    cx,1
  911.     add    ax,cx
  912.     adc    dx,0
  913.     div    denom            ; (256*xfer)/orig. ax = quo, dx = rem
  914.     mul    onehun            ; multiply quotient above by 100
  915.     mov    al,ah            ; divide result (ax) by 256
  916.     xor    ah,ah            ; percentage is in ax
  917.     jmp    short perpr4        ; finish in common code
  918. perpr3:    push    cx            ; case for file size > 64 KB
  919.     push    dx
  920.     mov    ax,diskio.sizelo    ; original file size low order word
  921.     shr    ax,1            ; divide by 2
  922.     mov    al,ah            ; divide again by 256 for total of 512
  923.     xor    ah,ah            ; clear ah        
  924.     mov    dx,diskio.sizehi    ; high order word
  925.     xchg    dh,dl            ; do shl dx,cl=7
  926.     ror    dx,1            ; old low bit of dh to high bit of dh
  927.     and    dl,80h            ; clear lower bits. divided by two
  928.     or    ax,dx            ; paste together the two parts into ax
  929.     mov    denom,ax        ; denom = original size divided by 512
  930.     mov    dx,tfilsz+2        ; high order word of transferred size
  931.     mov    ax,tfilsz        ; low order word
  932.     mov    cx,denom        ; round up, add half the denominator
  933.     shr    cx,1
  934.     add    ax,cx
  935.     adc    dx,0
  936.     div    denom            ; xfer/(orig/512). ax=quot, dx=rem
  937.     mul    onehun            ; times 100 for 512*percentage, in ax
  938.     mov    al,ah            ; divide ax by 512
  939.     xor    ah,ah
  940.     shr    al,1            ; final percentage, in ax
  941. perpr4:    cmp    ax,oldper        ; same as it was before?
  942.     je    perpr7            ; yes, don't bother printing
  943.     mov    oldper,ax        ; remember this for next time
  944.     cmp    wrpmsg,0        ; did we write the percentage message?
  945.     jne    perpr5            ; ne = yes, skip this part
  946.     push    ax
  947.     call    perpos            ; position cursor
  948.     mov    dx,offset permsg
  949.     mov    ah,prstr
  950.     int    dos            ; write out message
  951.     pop    ax
  952.     mov    wrpmsg,1        ; init flag so we don't do it again
  953. perpr5: push    ax
  954.     call    perpos            ; position the cursor
  955.     pop    ax
  956.     cmp    ax,onehun        ; > 100% ?
  957.     jle    perpr6            ; no, accept it
  958.     mov    ax,onehun        ; else just use 100
  959. perpr6:    call    decout
  960.     mov    dl,25h            ; load a percent sign
  961.     mov    ah,conout        ; display the character
  962.     int    dos
  963. perpr7:    pop    dx
  964.     pop    cx
  965.     ret
  966. perpr    endp
  967.  
  968. winpr    proc    near            ; print number of active window slots
  969.     cmp    trans.windo,1        ; windowing in use?
  970.     jbe    winprx            ; be = no, no message
  971.     test    flags.remflg,dregular    ; regular display?
  972.     jz    winprx            ; z = no, no display
  973.     cmp    fmtdsp,0        ; formatted display?
  974.     je    winprx            ; e = no, no display here
  975.     test    flags.remflg,dserver    ; server mode?
  976.     jnz    winpr4            ; nz = yes, writing to their screen
  977.     cmp    flags.xflg,0        ; receiving to screen?
  978.     je    winpr4            ; e = no
  979. winprx:    ret
  980. winpr4:    push    ax
  981.     push    bx
  982.     push    cx
  983.     push    dx
  984.     push    si
  985.     cmp    windflag,0        ; have we written an initial value?
  986.     jne    winpr1            ; ne = yes
  987.     mov    dx,scrnp        ; position cursor
  988.     dec    dh
  989.     xor    dl,dl            ; 0 = left most column for text
  990.     call    poscur
  991.     call    clearl            ; clear the line
  992.     mov    ah,prstr
  993.     mov    dx,offset windmsg    ; the text
  994.     int    dos
  995.     xor    al,al            ; display an initial 0
  996.     mov    oldwind,-1
  997.     mov    windflag,1        ; say have done the work
  998.     jmp    short winpr2
  999. winpr1:    mov    al,windused        ; window slots in use
  1000.     cmp    al,oldwind        ; same as before?
  1001.     je    winpr3            ; e = yes, ignore
  1002. winpr2:    push    ax
  1003.     mov    dx,scrnp        ; position cursor
  1004.     dec    dh
  1005.     call    poscur
  1006.     call    clearl
  1007.     pop    ax
  1008.     mov    oldwind,al        ; remember last value
  1009.     xor    ah,ah
  1010.     call    decout            ; display value
  1011.     mov    ah,prstr
  1012.     mov    dx,offset windmsg2    ; ' of '
  1013.     int    dos
  1014.     mov    al,trans.windo        ; number of window slots
  1015.     xor    ah,ah
  1016.     call    decout
  1017. winpr3:    pop    si
  1018.     pop    dx
  1019.     pop    cx
  1020.     pop    bx
  1021.     pop    ax
  1022.     ret
  1023. winpr    endp
  1024.  
  1025. code    ends
  1026.  
  1027. code1    segment
  1028.     assume    cs:code1
  1029.  
  1030. ; Start recording of statistics for this operation.
  1031. fbegtim    proc    FAR
  1032.     test    sflag,80h        ; is this a duplicate call?
  1033.     jz    begtim1            ; z = no
  1034.     ret                ; else just return
  1035. begtim1:push    ax
  1036.     push    cx
  1037.     push    dx
  1038.     push    di
  1039.     push    es
  1040.     push    ds
  1041.     pop    ds
  1042.     xor    ax,ax        ; clear statistics counters for this file
  1043.     cld
  1044.     mov    di,offset fsta.prbyte    ; start of the structure
  1045.     mov    cx,offset fsta.xstatus+1-offset fsta.prbyte ; end
  1046.     rep    stosb            ; clear most of the structure    [
  1047.     pop    es
  1048.     pop    di
  1049.     mov    ah,getdate        ; get current date, convert to ascii
  1050.     int    dos
  1051.     mov    date+9,'0'        ; init day of month
  1052. begtim2:cmp    dl,10            ; day of month. Ten or more days?
  1053.     jl    begtim3            ; l = no
  1054.     sub    dl,10
  1055.     inc    date+9            ; add up tens of days
  1056.     jmp    short begtim2        ; repeat for higher order
  1057. begtim3:add    dl,'0'            ; ascii bias
  1058.     mov    date+10,dl        ; day units
  1059.     mov    dl,dh            ; months (1-12)
  1060.     dec    dl            ; start at zero to index table
  1061.     xor    dh,dh
  1062.     mov    di,dx            ; months
  1063.     shl    di,1
  1064.     add    di,dx            ; times three chars/month
  1065.     mov    al,months[di]        ; get text string for month
  1066.     mov    date+12,al
  1067.     mov    ax,word ptr months[di+1]
  1068.     mov    word ptr date+13,ax
  1069.     mov    ax,cx            ; year since 1980
  1070.     mov    dx,0
  1071.     mov    di,offset date+16    ; destination
  1072.     call    flnout            ; convert number to asciiz in buffer
  1073.                     ; start time
  1074.     mov    ah,gettim        ; DOS time of day, convert to ascii
  1075.     int    dos
  1076.     mov    fsta.btime,dx        ; store ss.s   low word of seconds
  1077.     mov    fsta.btime+2,cx        ; store hhmm   high word of seconds
  1078.     mov    date,'0'        ; init begin hours field
  1079. begtim4:cmp    ch,10            ; ten or more hours?
  1080.     jl    begtim5            ; l = no
  1081.     sub    ch,10
  1082.     inc    date            ; add up tens of hours
  1083.     jmp    short begtim4        ; repeat for twenties
  1084. begtim5:add    ch,'0'            ; ascii bias
  1085.     mov    date+1,ch        ; store units of hours
  1086.     mov    date+3,'0'        ; minutes field
  1087. begtim6:cmp    cl,10            ; ten or more minutes?
  1088.     jl    begtim7            ; l = no
  1089.     sub    cl,10
  1090.     inc    date+3            ; add up tens of minutes
  1091.     jmp    short begtim6        ; repeat for higher orders
  1092. begtim7:add    cl,'0'            ; ascii bias
  1093.     mov    date+4,cl        ; store units of minutes
  1094.     mov    date+6,'0'        ; seconds field
  1095. begtim8:cmp    dh,10            ; ten or more seconds?
  1096.     jl    begtim9            ; l = no
  1097.     sub    dh,10
  1098.     inc    date+6            ; add up tens of seconds
  1099.     jmp    short begtim8        ; repeat for higher orders
  1100. begtim9:add    dh,'0'            ; ascii bias
  1101.     mov    date+7,dh
  1102.     mov    sflag,80h        ; say begtim has been run
  1103.     pop    dx
  1104.     pop    cx
  1105.     pop    ax
  1106.     ret
  1107. fbegtim    endp
  1108.  
  1109. ; Take snapshot of statistics counters at end of an operation
  1110. ; Enter with ax = 0 for a receive operation, ax = 1 for a send. [jrd]
  1111. fendtim    proc    FAR
  1112.     test    sflag,80h    ; called more than once without calling begtim?
  1113.     jnz    endtim1            ; ne = no, so do statistics snapshot
  1114.     ret                ; yes, do nothing
  1115. endtim1:and    sflag,not (1)        ; assume receive operation
  1116.     or    ax,ax            ; send (ax > 0), receive (ax = 0) flag
  1117.     jz    endtim2            ; z = receive opeation
  1118.     or    sflag,1            ; say send operation
  1119. endtim2:push    ax
  1120.     push    cx
  1121.     push    dx
  1122.     mov    ah,gettim        ; get DOS time of day
  1123.     int    dos
  1124.     mov    fsta.etime,dx        ; store ss. s
  1125.     mov    fsta.etime+2,cx        ; hhmm
  1126.     cmp    cx,fsta.btime+2        ; end time less than start time?
  1127.     ja    endtim2a    ; a = above (no need to test low order word)
  1128.     cmp    dx,fsta.btime        ; be. How about low order word
  1129.     jae    endtim2a        ; ae = no wrap around of time
  1130.     add    ch,24            ; add one day to hours field
  1131. endtim2a:sub    dl,byte ptr fsta.btime ; 0.01 sec difference
  1132.     jns    endtim2b
  1133.     dec    dh            ; borrow a second
  1134.     add    dl,100            ; make difference positive
  1135. endtim2b:sub    dh,byte ptr fsta.btime+1; seconds difference
  1136.     jns    endtim2c
  1137.     dec    cl            ; borrow a minute
  1138.     add    dh,60            ; make difference positive
  1139. endtim2c:xor    bh,bh
  1140.     mov    bl,dh            ; bx has seconds difference
  1141.     sub    cl,byte ptr fsta.btime+2 ; minutes
  1142.     jns    endtim2d
  1143.     dec    ch            ; borrow an hour
  1144.     add    cl,60
  1145. endtim2d:mov    al,cl
  1146.     xor    ah,ah
  1147.     mul    sixty            ; minutes to seconds
  1148.     add    bx,ax            ; seconds to bx
  1149.     sub    ch,byte ptr fsta.btime+3 ; hours difference
  1150.     jns    endtim2e
  1151.     add    ch,24
  1152. endtim2e:mov    al,ch
  1153.     xor    ah,ah
  1154.     mul    sixty            ; hours to minutes in ax
  1155.     mul    sixty            ; minutes to seconds in dx,ax
  1156.     add    ax,bx            ; ax = seconds
  1157.     adc    dx,0            ; dx = high word of seconds
  1158.     mov    fsta.etime,ax        ; store elapsed time, seconds, low wd
  1159.     mov    fsta.etime+2,dx        ; high word
  1160.     add    ssta.etime,ax        ; add to session time, low word
  1161.     adc    ssta.etime+2,dx        ; add to session time, high word
  1162.     mov    ax,fsta.pretry        ; retries for last transfer
  1163.     add    ssta.pretry,ax        ; retries for this session
  1164.  
  1165.     test    sflag,1            ; completing a receive operation?
  1166.     jnz    endtim3            ; nz = no, a send operation
  1167.     mov    ax,tfilsz        ; file bytes received, low word
  1168.     mov    fsta.frbyte,ax
  1169.     add    ssta.frbyte,ax        ; session received file bytes, low word
  1170.     mov    ax,tfilsz+2        ; high word
  1171.     mov    fsta.frbyte+2,ax
  1172.     adc    ssta.frbyte+2,ax
  1173.     jmp    short endtim4
  1174.  
  1175. endtim3:mov    ax,tfilsz        ; file bytes sent, low word
  1176.     mov    fsta.fsbyte,ax        ; file bytes sent
  1177.     add    ssta.fsbyte,ax        ; session sent file bytes, low word
  1178.     mov    ax,tfilsz+2        ; high word
  1179.     mov    fsta.fsbyte+2,ax
  1180.     adc    ssta.fsbyte+2,ax
  1181.  
  1182. endtim4:mov    ax,fsta.nakrcnt     ; NAKs received for this file
  1183.     add    ssta.nakrcnt,ax     ; session received NAKs
  1184.     mov    ax,fsta.nakscnt     ; NAKs sent for this file
  1185.     add    ssta.nakscnt,ax     ; session sent NAKs
  1186.                     ; do transaction logging
  1187.     cmp    tloghnd,0        ; logging transaction? -1 = not opened
  1188.     jg    endtim5            ; g = logging
  1189.     jmp    endtim12        ; skip logging
  1190. endtim5:push    di            ; kind of transaction
  1191.     push    bx            ; save these registers
  1192.     mov    bx,tloghnd        ; handle for transaction log
  1193.     mov    dx,offset rcvmsg    ; assume receive message
  1194.     test    sflag,1            ; 1 for send, 0 for receive
  1195.     jz    endtim6            ; z = receive
  1196.     mov    dx,offset sndmsg    ; send message
  1197. endtim6:call    fstrlen            ; length of message to cx
  1198.     mov    ah,write2
  1199.     int    dos            ; write kind of transfer
  1200.                     ; File names
  1201.     cmp    diskio.string,0        ; local filename
  1202.     je    endtim9            ; e = no filename
  1203.     test    sflag,1            ; a send operation?
  1204.     jnz    endtim8            ; nz = yes
  1205.                     ; Receive
  1206.     mov    dx,offset fsta.xname    ; remote name
  1207.     call    fstrlen            ; length to cx
  1208.     jcxz    endtim7            ; no name
  1209.     mov    ah,write2
  1210.     int    dos
  1211.     mov    dx,offset diskio.string    ; local name
  1212.     call    fstrlen            ; length to cx
  1213.     mov    si,offset fsta.xname    ; compare these two names
  1214.     mov    di,dx
  1215.     push    ds
  1216.     pop    es
  1217.     repe    cmpsb            ; compare
  1218.     je    endtim9            ; e = same, so no 'as' msg
  1219.     mov    dx,offset fasmsg    ; give 'as' message
  1220.     mov    cx,faslen        ; length
  1221.     mov    ah,write2
  1222.     int    dos
  1223. endtim7:mov    dx,offset diskio.string    ; local name
  1224.     call    fstrlen            ; get length
  1225.     mov    ah,write2        ; write local name
  1226.     int    dos
  1227.     jmp    short endtim9
  1228.  
  1229. endtim8:mov    dx,offset templp    ; Send. local name
  1230.     call    fstrlen
  1231.     mov    ah,write2
  1232.     int    dos
  1233.     cmp    fsta.xname,0        ; using an alias?
  1234.     je    endtim9            ; e = no
  1235.     mov    dx,offset fasmsg    ; give 'as' message
  1236.     mov    cx,faslen
  1237.     mov    ah,write2
  1238.     int    dos
  1239.     mov    dx,offset fsta.xname    ; get alias
  1240.     call    fstrlen
  1241.     mov    ah,write2
  1242.     int    dos
  1243.                     ; status of transfer
  1244. endtim9:mov    dx,offset atmsg        ; say At
  1245.     mov    cx,atlen        ; length
  1246.     mov    bx,tloghnd        ; handle
  1247.     mov    ah,write2
  1248.     int    dos
  1249.     mov    dx,offset date        ; write time and date field
  1250.     mov    cx,datelen        ; length
  1251.     mov    ah,write2
  1252.     int    dos
  1253.     mov    dx,offset fsucmsg    ; assume success message
  1254.     cmp    fsta.xstatus,kssuc    ; 0 = completed successfully?
  1255.     je    endtim10        ; e = completed
  1256.     mov    dx,offset fbadmsg    ; failed message
  1257.     test    fsta.xstatus,ksuser    ; user interrupted?
  1258.     jz    endtim10        ; z = no
  1259.     mov    dx,offset fintmsg    ; interrupted message
  1260. endtim10:call    fstrlen            ; get length to cx
  1261.     mov    ah,write2
  1262.     int    dos
  1263.                     ; file bytes transferred
  1264.     mov    ax,tfilsz        ; file bytes, low word
  1265.     mov    dx,tfilsz+2        ; high word
  1266.     mov    di,offset rdbuf        ; work buffer
  1267.     call    flnouts            ; transform to ascii
  1268.     mov    [di],0a0dh        ; append cr/lf
  1269.     add    di,2            ; count them
  1270.     mov    dx,offset rdbuf        ; start of work buffer
  1271.     mov    cx,di            ; next free byte
  1272.     sub    cx,dx            ; compute length
  1273.     mov    ah,write2
  1274.     int    dos
  1275.     cmp    dosnum,300h+30        ; DOS 3.30 or higher?
  1276.     jb    endtim11        ; b = no
  1277.     mov    ah,68h            ; Commit the file now
  1278.     int    dos
  1279. endtim11:pop    bx
  1280.     pop    di
  1281. endtim12:mov    tfilsz,0        ; clear file size area
  1282.     mov    tfilsz+2,0
  1283.     mov    sflag,0            ; say have done ending once already
  1284.     mov    fsta.xname,0        ; clear statistics "as" name
  1285.     pop    dx
  1286.     pop    cx
  1287.     pop    ax
  1288.     ret
  1289. fendtim    endp
  1290.  
  1291. fshosta    proc    far
  1292.     push    bx
  1293.     push    cx
  1294.     push    dx
  1295.     push    di
  1296.     mov    dx,offset statmsg    ; header
  1297.     mov    ah,prstr
  1298.     int    dos
  1299.     mov    dx,offset fchmsg    ; File characters msg
  1300.     mov    ah,prstr
  1301.     int    dos
  1302.     mov    di,offset ssta        ; session structure
  1303.     mov    bx,offset fsta        ; last file structure
  1304.     mov    ax,[bx].fsbyte        ; last transfer file bytes sent
  1305.     mov    dx,[bx].fsbyte+2
  1306.     mov    cx,12            ; field width
  1307.     call    shoprt            ; show result
  1308.     mov    ax,[bx].frbyte        ; last transfer file bytes received
  1309.     mov    dx,[bx].frbyte+2
  1310.     call    shoprt            ; show result
  1311.     mov    ax,[di].fsbyte        ; session file bytes sent
  1312.     mov    dx,[di].fsbyte+2
  1313.     call    shoprt            ; show result
  1314.     mov    ax,[di].frbyte        ; session file bytes received
  1315.     mov    dx,[di].frbyte+2
  1316.     call    shoprt            ; show result
  1317.  
  1318.     mov    ah,prstr
  1319.     mov    dx,offset spmsg        ; serial port material
  1320.     int    dos
  1321.     mov    ax,[bx].psbyte        ; last transfer port bytes sent
  1322.     mov    dx,[bx].psbyte+2
  1323.     call    shoprt            ; show result
  1324.     mov    ax,[bx].prbyte        ; last transfer port bytes received
  1325.     mov    dx,[bx].prbyte+2
  1326.     call    shoprt            ; show result
  1327.     mov    ax,[di].psbyte        ; session port bytes sent
  1328.     mov    dx,[di].psbyte+2
  1329.     call    shoprt            ; show result
  1330.     mov    ax,[di].prbyte        ; session port bytes received
  1331.     mov    dx,[di].prbyte+2
  1332.     call    shoprt            ; show result
  1333.  
  1334.     mov    dx,offset pktmsg    ; packets material
  1335.     mov    ah,prstr
  1336.     int    dos
  1337.     mov    ax,[bx].pspkt        ; last transfer packets sent
  1338.     mov    dx,[bx].pspkt+2
  1339.     call    shoprt            ; show result
  1340.     mov    ax,[bx].prpkt        ; last transfer packets received
  1341.     mov    dx,[bx].prpkt+2
  1342.     call    shoprt            ; show result
  1343.     mov    ax,[di].pspkt        ; session packets sent
  1344.     mov    dx,[di].pspkt+2
  1345.     call    shoprt            ; show result
  1346.     mov    ax,[di].prpkt        ; session packets received
  1347.     mov    dx,[di].prpkt+2
  1348.     call    shoprt            ; show result
  1349.  
  1350.     mov    dx,offset nakmsg    ; NAKs material
  1351.     mov    ah,prstr
  1352.     int    dos
  1353.     mov    ax,[bx].nakscnt        ; last transfer NAKs sent
  1354.     xor    dx,dx
  1355.     call    shoprt
  1356.     mov    ax,[bx].nakrcnt        ; last transfer NAKs received
  1357.     xor    dx,dx
  1358.     call    shoprt
  1359.     mov    ax,[di].nakscnt        ; session NAKs sent
  1360.     xor    dx,dx
  1361.     call    shoprt
  1362.     mov    ax,[di].nakrcnt        ; session NAKs received
  1363.     xor    dx,dx
  1364.     call    shoprt
  1365.  
  1366.     mov    dx,offset retmsg    ; retries
  1367.     mov    ah,prstr
  1368.     int    dos
  1369.     mov    ax,[bx].pretry        ; last transfer retry count
  1370.     xor    dx,dx
  1371.     mov    cx,18
  1372.     call    shoprt
  1373.     mov    ax,[di].pretry        ; session retries
  1374.     xor    dx,dx
  1375.     mov    cx,24
  1376.     call    shoprt
  1377.  
  1378.     mov    dx,offset timemsg    ; elapsed time material
  1379.     mov    ah,prstr
  1380.     int    dos
  1381.     mov    ax,[bx].etime        ; elapsed time of last transfer
  1382.     mov    dx,[bx].etime+2
  1383.     mov    cx,18
  1384.     call    shoprt            ; show result
  1385.     mov    ax,[di].etime        ; elapsed time of session
  1386.     mov    dx,[di].etime+2
  1387.     mov    cx,24
  1388.     call    shoprt            ; show result
  1389.  
  1390.     mov    dx,offset chpsmsg    ; File chars per second
  1391.     mov    ah,prstr
  1392.     int    dos
  1393.     mov    ax,[bx].frbyte        ; file bytes received, low
  1394.     mov    dx,[bx].frbyte+2    ; file bytes received, high
  1395.     add    ax,[bx].fsbyte        ; file bytes sent, low
  1396.     adc    dx,[bx].fsbyte+2    ;  high. [dx,ax] = total file bytes
  1397.     call    showrk            ; do worker
  1398.     xor    dx,dx            ; discard the fractional cps
  1399.     mov    cx,18
  1400.     call    shoprt            ; show result
  1401.     xchg    bx,di            ; swap session and last file pointers
  1402.     mov    ax,[bx].frbyte        ; file bytes received, low
  1403.     mov    dx,[bx].frbyte+2    ; file bytes received, high
  1404.     add    ax,[bx].fsbyte        ; file bytes sent, low
  1405.     adc    dx,[bx].fsbyte+2    ;  high. [dx,ax] = total file bytes
  1406.     call    showrk            ; do worker
  1407.     xchg    bx,di            ; unswap session and last file pointers
  1408.     xor    dx,dx            ; discard the fractional cps
  1409.     mov    cx,24
  1410.     call    shoprt            ; show result
  1411.         
  1412.     mov    dx,offset spedmsg    ; speed material
  1413.     mov    ah,prstr
  1414.     int    dos
  1415.         ; compute baud rate as  10 * total port bytes / elapsed time
  1416.     mov    ax,[bx].prbyte        ; port bytes received, low
  1417.     mov    dx,[bx].prbyte+2    ; port bytes received, high
  1418.     add    ax,[bx].psbyte        ; port bytes sent, low
  1419.     adc    dx,[bx].psbyte+2    ;  high. [dx,ax] = total port bytes
  1420.     call    showrk            ; do worker for bytes/sec and fraction
  1421.     mov    cx,dx            ; save remainder of bytes/second
  1422.     mul    ten            ; bytes/sec times ten to dx,ax
  1423.     push    dx            ; save high order part
  1424.     push    ax            ; save partial baud rate
  1425.     mov    ax,cx            ; remainder to ax
  1426.     xor    dx,dx            ; clear extension
  1427.     mul    ten        ; remainder times ten too (keep only overflow)
  1428.     mov    cx,dx            ; overflow part
  1429.     pop    ax            ; recover main partial result
  1430.     pop    dx            ; high order part
  1431.     add    ax,cx            ; add two partial results
  1432.     adc    dx,0            ; add to extension
  1433.     mov    cx,18
  1434.     call    shoprt            ; show result
  1435.     xchg    bx,di            ; swap session and last file pointers
  1436.     mov    ax,[bx].prbyte        ; port bytes received, low
  1437.     mov    dx,[bx].prbyte+2    ; port bytes received, high
  1438.     add    ax,[bx].psbyte        ; port bytes sent, low
  1439.     adc    dx,[bx].psbyte+2    ;  high. [dx,ax] = total port bytes
  1440.     mov    bx,offset ssta
  1441.     call    showrk            ; do worker for bytes/sec and fraction
  1442.     mov    cx,dx            ; save remainder of bytes/second
  1443.     mul    ten            ; bytes/sec times ten to dx,ax
  1444.     push    dx            ; save high order part
  1445.     push    ax            ; save partial baud rate
  1446.     mov    ax,cx            ; remainder to ax
  1447.     xor    dx,dx            ; clear extension
  1448.     mul    ten        ; remainder times ten too (keep only overflow)
  1449.     mov    cx,dx            ; overflow part
  1450.     pop    ax            ; recover main partial result
  1451.     pop    dx            ; high order part
  1452.     add    ax,cx            ; add two partial results
  1453.     adc    dx,0            ; add to extension
  1454.     mov    cx,24
  1455.     call    shoprt            ; show result
  1456.  
  1457.     mov    ah,prstr
  1458.     mov    dx,offset crlf
  1459.     int    dos
  1460.     pop    di
  1461.     pop    dx
  1462.     pop    cx
  1463.     pop    bx
  1464.     clc
  1465.     ret
  1466. fshosta    endp
  1467.  
  1468. ; Display SHOW STATISTICS line. Enter with dx,ax with long value, cx = width
  1469. shoprt    proc    near
  1470.     push    di
  1471.     mov    di,offset rdbuf        ; work space for output
  1472.     call    flnouts            ; show long integer, with separator
  1473.     pop    di
  1474.     mov    dx,offset rdbuf
  1475.     push    bx
  1476.     push    cx
  1477.     push    dx
  1478.     mov    bx,cx            ; field width
  1479.     call    fstrlen            ; length of string in dx
  1480.     sub    bx,cx            ; number of spaces necessary
  1481.     xchg    bx,cx
  1482.     jle    shoprt2            ; le = no spaces
  1483.     mov    dl,' '
  1484.     mov    ah,conout
  1485. shoprt1:int    dos            ; display the leading spaces
  1486.     loop    shoprt1
  1487. shoprt2:pop    dx
  1488.     pop    cx
  1489.     pop    bx
  1490.     call    fprtasz            ; display asciiz string
  1491.     ret
  1492. shoprt    endp
  1493.  
  1494. ; baud rate and char/sec worker for above
  1495. ; Enter with dx,ax holding the byte count, returns (dx,ax / seconds in
  1496. ; ax (whole number) and dx (fraction).
  1497. showrk    proc    near    
  1498.     mov    cx,[bx].etime        ; low word of sec in cx
  1499.     cmp    [bx].etime+2,0    ; is high word of sec zero (e.t. < 65536 sec)?
  1500.     jz    showrk1            ; z = yes, ready for arithmetic
  1501.     push    ax            ; else scale values, save byte count
  1502.     push    dx
  1503.     mov    ax,[bx].etime        ; elapsed time for file, low word
  1504.     mov    dx,[bx].etime+2        ;  high word    
  1505.     shr    ax,1            ; divide seconds by two, low word
  1506.     ror    dx,1            ; get low bit of high word
  1507.     and    dx,8000            ; pick out just that bit
  1508.     or    ax,dx        ; mask in that bit, new time in ax (dx = 0)
  1509.     mov    cx,ax            ; save elapsed time (double-seconds)
  1510.     pop    dx            ; get byte count again
  1511.     pop    ax
  1512.     shr    ax,1            ; divide byte count by two also
  1513.     push    dx
  1514.     ror    dx,1            ; rotate low bit to high position
  1515.     and    dx,8000h        ; get low bit of high word
  1516.     or    ax,dx            ; byte count divided by two, low word
  1517.     pop    dx
  1518.     shr    dx,1            ; and high word
  1519. showrk1:or    cx,cx               ; is elapsed time (in cx) zero seconds?
  1520.     jnz    showrk2            ; nz = no
  1521.     inc    cx                ; set time to one second (no div by 0)
  1522. showrk2:div    cx               ; bytes div seconds, ax = quo, dx = rem
  1523.     ret
  1524. showrk    endp
  1525.  
  1526.  
  1527. fshomdef proc    FAR            ; worker, show mac name and def
  1528.     push    ax            ; call with si pointing at macro
  1529.     push    si            ; name, word ptr [si-2] = length
  1530.     push    es
  1531.     cmp    byte ptr[si],0        ; name starts with null char?
  1532.     jne    shomd1            ; ne = no
  1533.     jmp    shomd9            ; yes, TAKE file, ignore
  1534. shomd1:    call    shomdl            ; do newline, check for more/exit
  1535.     jnc    shomd2            ; nc = continue
  1536.     jmp    shomd9            ; exit
  1537. shomd2:    mov    ah,conout
  1538.     mov    dl,' '            ; add a space
  1539.     int    dos
  1540.     inc    bx
  1541.     inc    temp            ; count displayed macros
  1542.     push    cx
  1543.     push    di
  1544.     mov    cx,[si-2]        ; length of definition
  1545.     mov    di,si            ; offset for printing
  1546.     call    fprtscr            ; print counted string
  1547.     pop    di
  1548.     pop    cx
  1549.     mov    ah,prstr
  1550.     mov    dx,offset eqs        ; display equals sign
  1551.     int    dos
  1552.     mov    denom,1            ; set flag to do "," to <cr>
  1553.     cmp    word ptr [si],'%\'    ; substitution variable?
  1554.     jne    shomd2a            ; ne = no
  1555.     mov    denom,0            ; clear bare comma sensitivity flag
  1556. shomd2a:mov    ax,[si-2]        ; length of macro name
  1557.     add    si,ax            ; skip over name
  1558.     add    bx,ax            ; count of chars on line
  1559.     add    bx,3            ; plus " = "
  1560.     mov    es,[si]            ; segment of string structure
  1561.     xor    si,si            ; es:si = address of count + string
  1562.     mov    cx,es:[si]        ; length of string
  1563.     add    si,2            ; si = offset of string text proper
  1564. shomd3:    mov    al,es:[si]        ; get a byte into al
  1565.     inc    si
  1566.     call    shombrk            ; examine for bare comma break
  1567.     cmp    al,' '            ; control char?
  1568.     jae    shomd5            ; ae = no
  1569.     cmp    al,cr            ; carriage return?
  1570.     jne    shomd4            ; ne = no
  1571.     mov    ah,prstr
  1572.     mov    dx,offset shom9m4    ; show <cr>
  1573.     int    dos
  1574.     add    bx,4            ; chars on line
  1575.     cmp    cx,1            ; more to show?
  1576.     je    shomd6            ; e = no
  1577.     call    shomdl            ; new line, check for continue or exit
  1578.     jc    shomd9            ; c = exit
  1579.     mov    ah,conout        ; show two spaces
  1580.     mov    dl,' '            ; the spaces
  1581.     int    dos
  1582.     int    dos
  1583.     add    bx,2
  1584.     cmp    byte ptr es:[si],lf    ; cr followed by linefeed?
  1585.     jne    short shomd6        ; ne = no
  1586.     inc    si            ; skip the leading lf
  1587.     dec    cx
  1588.     jmp    short shomd6
  1589. shomd4:    push    ax
  1590.     mov    ah,conout
  1591.     mov    dl,5eh            ; caret
  1592.     int    dos
  1593.     pop    ax
  1594.     inc    bx
  1595.     add    al,'A'-1        ; add offset to make printable letter
  1596. shomd5:    mov    ah,conout
  1597.     mov    dl,al            ; display it
  1598.     int    dos
  1599.     inc    bx
  1600. shomd6:    cmp    bx,75            ; time to break the line?
  1601.     jb    shomd8            ; b = no
  1602.     cmp    bx,76            ; at an absolute break point
  1603.     jae    shomd7            ; ae = yes
  1604.     cmp    byte ptr es:[si],' '    ; is next char a space?
  1605.     je    shomd8            ; e = yes, show explicitly
  1606. shomd7:    mov    ah,conout        ; display a line break hyphen
  1607.     mov    dl,'-'
  1608.     int    dos
  1609.     call    shomdl            ; check for screen full
  1610.     jc    shomd9            ; c = exit now
  1611.     mov    ah,conout        ; show two spaces
  1612.     xor    bx,bx            ; column counter
  1613. shomd8:    loop    shomd3            ; do whole string
  1614. shomd9:    pop    es
  1615.     pop    si
  1616.     pop    ax
  1617.     ret
  1618.                       ; worker, do "more" and Control-C checking
  1619. shomdl    proc    near
  1620.     inc    temp1            ; count lines displayed
  1621.     xor    bx,bx            ; count of chars on the line
  1622.     cmp    temp1,24        ; done a normal screens' worth?
  1623.     jb    shomdl2            ; b = no
  1624.     mov    ah,prstr
  1625.     mov    dx,offset moremsg    ; say more
  1626.     int    dos
  1627.     mov    temp1,0
  1628.     mov    flags.cxzflg,0        ; clear flag so we can see Control-C
  1629.     mov    ah,0ch            ; clear keyboard buffer
  1630.     mov    al,coninq        ; quiet input
  1631.     int    dos
  1632.     cmp    al,3            ; Control-C?
  1633.     je    shomdl1            ; e = yes
  1634.     cmp    al,'q'            ; q for quit?
  1635.     je    shomdl1            ; e = yes
  1636.     cmp    al,'Q'            ; Q for quit?
  1637.     je    shomdl1            ; e = yes
  1638.     or    al,al            ; scan code?
  1639.     jne    shomdl2            ; ne = no
  1640.     mov    ah,coninq        ; read the second byte
  1641.     int    dos
  1642.     or    al,al            ; null for Control-Break?
  1643.     jne    shomdl2            ; ne = no
  1644. shomdl1:mov    flags.cxzflg,'C'    ; say want to exit now
  1645. shomdl2:mov    ah,prstr
  1646.     mov    dx,offset crlf
  1647.     int    dos
  1648.     cmp    flags.cxzflg,0        ; want to exit?
  1649.     jne    shomdl3            ; ne = yes
  1650.     clc
  1651.     ret
  1652. shomdl3:stc                ; say exit now
  1653.     ret
  1654. shomdl    endp
  1655.  
  1656. ; Examine char in al. If it is a bare comma and byte ptr denom is non-zero
  1657. ; then change AL to Carriage return else return AL unchanged.
  1658. shombrk    proc    near
  1659.     push    dx
  1660.     mov    dx,denom        ; dh=brace cnt, dl=1 for sensitivity
  1661.     or    dl,dl            ; worry about bare commas?
  1662.     jz    shombr3            ; z = no
  1663.     cmp    al,braceop        ; opening brace?
  1664.     jne    shombr1            ; ne = no
  1665.     inc    dh            ; count brace level
  1666. shombr1:cmp    al,bracecl        ; closing brace?
  1667.     jne    shombr2
  1668.     sub    dh,1            ; count down brace level
  1669.     jns    shombr2            ; ns = not below zero
  1670.     xor    dh,dh            ; set brace level to zero
  1671. shombr2:mov    denom,dx        ; store our brace state
  1672.     or    dh,dh            ; inside braces?
  1673.     jnz    shombr3            ; nz = yes
  1674.     cmp    al,','            ; bare comma?
  1675.     jne    shombr3            ; ne = no
  1676.     mov    al,CR            ; replace with bare CR
  1677. shombr3:pop    dx
  1678.     ret
  1679. shombrk    endp
  1680. fshomdef endp
  1681.  
  1682. fshovar    proc    FAR            ; worker for SHOW VARIABLE, SHOVAR
  1683.     cmp    word ptr rdbuf,'v\'    ; did user say \v(name)?
  1684.     jne    fshova2            ; ne = no
  1685.     mov    di,offset rdbuf        ; start plus count
  1686.     mov    si,di
  1687.     add    si,3            ; remove \v(
  1688.     mov    cx,shmcnt        ; length of user spec
  1689.     sub    cx,3
  1690.     mov    shmcnt,cx        ; remember "variable)" part
  1691.     jle    fshova1            ; le = nothing left
  1692.     inc    cx            ; include null in the move
  1693.     mov    ax,ds
  1694.     mov    es,ax
  1695.     cld
  1696.     rep    movsb            ; copy down
  1697.     mov    si,offset rdbuf
  1698.     add    si,shmcnt
  1699.     cmp    byte ptr [si-1],')'    ; did user say ')'?
  1700.     jne    fshova2            ; ne = no
  1701.     mov    byte ptr [si-1],0    ; remove it
  1702.     dec    shmcnt
  1703.     jmp    short fshova2
  1704. fshova1:mov    shmcnt,0        ; make user entry empty
  1705. fshova2:mov    si,offset valtab    ; table of variable names
  1706.     cld
  1707.     lodsb
  1708.     mov    cl,al            ; number of variable entries
  1709.     xor    ch,ch
  1710.     jcxz    fshova7            ; z = none
  1711. fshova3:push    cx            ; save loop counter
  1712.     lodsw                ; length of var name, incl ')'
  1713.     mov    cx,shmcnt        ; length of user's string
  1714.     jcxz    fshova5            ; show all names
  1715.     push    ax            ; save length
  1716.     dec    ax            ; omit ')'
  1717.     cmp    ax,cx            ; var name shorter that user spec?
  1718.     pop    ax            ; recover full length
  1719.     jb    fshova6            ; b = yes, no match
  1720.     push    ax
  1721.     push    si            ; save these around match test
  1722.     mov    di,offset rdbuf        ; user's string
  1723. fshova4:mov    ah,[di]
  1724.     inc    di
  1725.     lodsb                ; al = var name char, ah = user char
  1726.     and    ax,not 2020h        ; clear bits (uppercase chars)
  1727.     cmp    ah,al            ; same?
  1728.     loope    fshova4            ; while equal, do more
  1729.     pop    si            ; restore regs
  1730.     pop    ax
  1731.     jne    fshova6            ; ne = no match
  1732. fshova5:call    fshova8            ; show this name
  1733. fshova6:add    si,ax            ; point to next name, add name length
  1734.     add    si,2            ; and string pointer
  1735.     pop    cx            ; recover loop counter
  1736.     cmp    flags.cxzflg,0        ; does user wish to stop now?
  1737.     jne    fshova7            ; ne = yes
  1738.     loop    fshova3            ; one less macro to examine
  1739. fshova7:mov    flags.cxzflg,0        ; clear flag before exiting
  1740.     ret
  1741.  
  1742. fshova8    proc    near            ; worker for above
  1743.     push    ax
  1744.     mov    ah,prstr
  1745.     mov    dx,offset varstng    ; put out <cr><lf>" \v("
  1746.     int    dos
  1747.     push    si
  1748.     push    cx
  1749.     mov    cx,[si-2]        ; length of name
  1750. fshova9:mov    dl,[si]            ; get a variable character
  1751.     inc    si            ; prep for next char
  1752.     mov    ah,conout
  1753.     int    dos
  1754.     loop    fshova9            ; do the count
  1755.     mov    dl,' '            ; display " = "
  1756.     int    dos
  1757.     mov    dl,'='
  1758.     int    dos
  1759.     mov    dl,' '
  1760.     int    dos
  1761.     mov    bx,[si]            ; get result code to bx
  1762.     xor    dx,dx            ; trim off trailing spaces
  1763.     call    fnvaltoa        ; fill valbuf with string
  1764.     jc    fshova10        ; c = failure
  1765.     mov    cx,di            ; di is string length
  1766.     mov    di,offset valbuf+2    ; string text (skips count word)
  1767.     call    fprtscr            ; display counted string
  1768. fshova10:pop    cx
  1769.     pop    si
  1770.     pop    ax
  1771.     ret
  1772. fshova8    endp                ; end of worker
  1773. fshovar    endp
  1774.  
  1775. code1    ends
  1776.  
  1777. code    segment
  1778.     assume cs:code
  1779.  
  1780. ; SHOW TRANSLATE-RECEIVE
  1781. ; Display characters being changed for Connect mode serial receive translator
  1782.  
  1783. SHORX    PROC    NEAR            ; show translate table of incoming
  1784.                     ; chars, only those changed
  1785.     mov    ah,cmeol        ; get a confirm
  1786.     call    comnd
  1787.     jnc    shorx0a            ; nc = success
  1788.     ret                ; failure
  1789. shorx0a:
  1790.     mov    ah,prstr
  1791.     mov    dx,offset crlf
  1792.     int    dos
  1793.     mov    bx,offset shorxk    ; show keyboard translation
  1794.     call    statc
  1795.     mov    ah,prstr
  1796.     mov    dx,offset rxoffmsg    ; assume translation is off
  1797.     cmp    rxtable+256,0        ; is translation off?
  1798.     je    shorx0            ; e = yes
  1799.     mov    dx,offset rxonmsg    ; say translation is on
  1800. shorx0:    int    dos
  1801.     mov    dx,offset shormsg    ; give title line
  1802.     int    dos
  1803.     xor    cx,cx            ; formatted line counter
  1804.     xor    bx,bx            ; entry subscript
  1805. shorx1:    cmp    rxtable[bx],bl        ; entry same as normal?
  1806.     je    shorx2            ; e = yes, skip it
  1807.     call    shorprt            ; display the entry
  1808. shorx2:    inc    bx            ; next entry
  1809.     cmp    bx,255            ; done all entries yet?
  1810.     jbe    shorx1            ; be = not yet
  1811.     mov    ah,prstr
  1812.     mov    dx,offset crlf        ; end with cr/lf
  1813.     int    dos
  1814.     clc                ; success
  1815.     ret
  1816.                     ; worker routine
  1817. shorprt:cmp    cx,4            ; done five entries for this line?
  1818.     jb    shorpr1            ; b = no
  1819.     mov    ah,prstr
  1820.     mov    dx,offset crlf        ; break line now
  1821.     int    dos
  1822.     xor    cx,cx
  1823. shorpr1:mov    ah,prstr
  1824.     mov    dx,offset shopm1    ; start of display
  1825.     int    dos
  1826.     xor    ah,ah
  1827.     mov    al,bl            ; original byte code
  1828.     call    decout            ; display its value
  1829.     mov    ah,prstr
  1830.     mov    dx,offset shopm2    ; intermediate part of display
  1831.     int    dos
  1832.     xor    ah,ah
  1833.     mov    al,rxtable[bx]        ; new byte code
  1834.     call    decout            ; display its value
  1835.     mov    ah,prstr
  1836.     mov    dx,offset shopm3    ; last part of display
  1837.     int    dos
  1838.     inc    cx            ; count item displayed
  1839.     ret
  1840. SHORX    ENDP
  1841.  
  1842. ; SHOW MACRO [macro name]
  1843.  
  1844. SHOMAC    PROC    NEAR
  1845.     mov    ah,cmword
  1846.     mov    dx,offset rdbuf
  1847.     mov    bx,offset shmmsg
  1848.     mov    comand.cmper,1        ; don't react to \%x variables
  1849.     call    comnd
  1850.     jnc    shoma1a            ; nc = success
  1851.     ret                ; failure
  1852. shoma1a:mov    shmcnt,ax        ; save length of user spec
  1853.     mov    ah,cmeol
  1854.     call    comnd
  1855.     jnc    shoma1b            ; nc = success
  1856.     ret                ; failure
  1857. shoma1b:mov    si,offset mcctab    ; table of macro names
  1858.     cld
  1859.     lodsb
  1860.     mov    cl,al            ; number of macro entries
  1861.     xor    ch,ch
  1862.     jcxz    shom6            ; z = none
  1863.     mov    temp,0            ; count of macros displayed
  1864.     mov    temp1,0            ; lines displayed, for more message
  1865. shom2:    push    cx            ; save loop counter
  1866.     lodsw                ; length of macro name
  1867.     mov    cx,shmcnt        ; length of user's string
  1868.     jcxz    shom4            ; show all names
  1869.     cmp    ax,cx            ; mac name shorter that user spec?
  1870.     jb    shom5            ; b = yes, no match
  1871.     push    ax
  1872.     push    si            ; save these around match test
  1873.     mov    di,offset rdbuf        ; user's string
  1874. shom3:    mov    ah,[di]
  1875.     inc    di
  1876.     lodsb                ; al = mac name char, ah = user char
  1877.     and    ax,not 2020h        ; clear bits (uppercase chars)
  1878.     cmp    ah,al            ; same?
  1879.     loope    shom3            ; while equal, do more
  1880.     pop    si            ; restore regs
  1881.     pop    ax
  1882.     jne    shom5            ; ne = no match
  1883. shom4:    call    fshomdef        ; show this name (FAR)
  1884. shom5:    add    si,ax            ; point to next name, add name length
  1885.     add    si,2            ;  and string pointer
  1886.     pop    cx            ; recover loop counter
  1887.     cmp    flags.cxzflg,0        ; does user wish to stop now?
  1888.     jne    shom5a            ; ne = yes
  1889.     loop    shom2            ; one less macro to examine
  1890. shom5a:    mov    flags.cxzflg,0        ; clear flag before exiting
  1891.     cmp    temp,0            ; did we show any macros?
  1892.     jne    shom7            ; ne = yes
  1893. shom6:    mov    ah,prstr
  1894.     mov    dx,offset shom9m3    ; no entries found
  1895.     int    dos
  1896. shom7:    mov    ah,prstr        ; Summary line
  1897.     mov    dx,offset shom9m1    ; free space: name entries
  1898.     int    dos
  1899.     mov    ax,offset mcctab+mcclen
  1900.     sub    ax,mccptr        ; compute # of free name bytes
  1901.     call    decout
  1902.     mov    ah,prstr
  1903.     mov    dx,offset crlf
  1904.     int    dos
  1905.     clc                ; success
  1906.     ret
  1907. SHOMAC    ENDP
  1908.  
  1909. SHCOM    PROC    NEAR            ; Show Modem
  1910.     mov    ah,cmeol
  1911.     call    comnd            ; get a confirm
  1912.     jc    shcom1            ; c = failure
  1913.     mov    dx,offset crlf
  1914.     mov    ah,prstr
  1915.     int    dos            ; print a crlf
  1916.     mov    bx,offset stcom        ; table of items to be shown
  1917.     call    statc            ; finish in common code
  1918.     call    shomodem
  1919.     clc
  1920. shcom1:    ret
  1921. SHCOM    ENDP
  1922.  
  1923. SHFILE    PROC    NEAR            ; Show File
  1924.     mov    ah,cmeol
  1925.     call    comnd            ; get a confirm
  1926.     jnc    shfile1            ; nc = success
  1927.     ret                ; failure
  1928. shfile1:mov    dx,offset crlf
  1929.     mov    ah,prstr
  1930.     int    dos            ; print a crlf
  1931.     mov    bx,offset stfile    ; table of items to be shown
  1932.     jmp    statc            ; finish in common code
  1933. SHFILE    ENDP
  1934.  
  1935. SHLOG    PROC    NEAR            ; Show Log
  1936.     mov    ah,cmeol
  1937.     call    comnd            ; get a confirm
  1938.     jnc    shlog1            ; nc = success
  1939.     ret                ; failure
  1940. shlog1:    mov    dx,offset crlf
  1941.     mov    ah,prstr
  1942.     int    dos            ; print a crlf
  1943.     mov    bx,offset stlog        ; table of items to be shown
  1944.     jmp    statc            ; finish in common code
  1945. SHLOG    ENDP
  1946.  
  1947. SHMEM    PROC    NEAR            ; Show (free) Memory.   Recursive!
  1948.     mov    ah,cmeol
  1949.     call    comnd            ; get a confirm
  1950.     jnc    shmem1            ; nc = success
  1951.     ret                ; failure
  1952. shmem1:    mov    ah,prstr
  1953.     mov    dx,offset memmsg1    ; header message
  1954.     int    dos
  1955.     mov    word ptr rdbuf,'  '    ; two spaces
  1956.     mov    rdbuf+2,0        ; safety null terminator
  1957.     mov    di,offset rdbuf+1    ; look at first space
  1958.     mov    temp,0            ; total free memory
  1959.     mov    temp1,0            ;  and high word thereof
  1960.     push    es            ; save es
  1961.     call    shmem4            ; allocate memory, recursively
  1962.     mov    dx,offset rdbuf        ; output buffer
  1963.     call    prtasz            ; show pieces
  1964.     mov    dx,offset memmsg2    ; trailer
  1965.     mov    ah,prstr
  1966.     int    dos
  1967.     mov    di,offset rdbuf        ; setup buffer for lnout
  1968.     mov    rdbuf,0
  1969.     mov    ax,temp            ; total free space
  1970.     mov    dx,temp1
  1971.     call    lnouts            ; 32 bit to decimal ascii in di
  1972.     mov    dx,offset rdbuf        ;  with thousands separator
  1973.     call    prtasz
  1974.     pop    es
  1975.     ret
  1976.                     ; worker routine
  1977. shmem4:    mov    bx,0ffffh        ; allocate all memory (must fail)
  1978.     mov    ah,alloc        ; DOS memory allocator
  1979.     int    dos            ; returns available paragraphs in bx
  1980.     jnc    shmem6            ; nc = got it all (not very likely)
  1981.     or    bx,bx            ; bx = # paragraphs alloc'd. Anything?
  1982.     jz    shmem5            ; z = no
  1983.     mov    ah,alloc        ; consume qty now given in bx
  1984.     int    dos
  1985.     jnc    shmem6            ; nc = got the fragment
  1986. shmem5:    ret
  1987. shmem6:    push    ax            ; save allocation segment
  1988.     mov    ax,bx            ; convert paragraphs
  1989.     mul    sixteen            ;  to bytes in dx:ax
  1990.     add    temp,ax            ; running total
  1991.     adc    temp1,dx        ;  32 bits
  1992.     cmp    byte ptr [di],0        ; starting on a null?
  1993.     jne    shmem7            ; ne = no, skip punctuation
  1994.     mov    byte ptr [di],'+'    ; plus punctuation
  1995.     inc    di
  1996. shmem7:    call    lnouts            ; long number to decimal in buffer di
  1997.     call    shmem4            ; recurse
  1998.     pop    es            ; recover allocation segment
  1999.     mov    ah,freemem        ; free the allocation
  2000.     int    dos
  2001.     ret
  2002. SHMEM    ENDP
  2003.  
  2004. SHPRO    PROC    NEAR            ; Show Protocol
  2005.     mov    ah,cmeol
  2006.     call    comnd            ; get a confirm
  2007.     jnc    shpro1            ; nc = success
  2008.     ret                ; failure
  2009. shpro1:    mov    dx,offset crlf
  2010.     mov    ah,prstr
  2011.     int    dos            ; print a crlf
  2012.     mov    bx,offset stpro        ; table of items to be shown
  2013.     jmp    statc            ; finish in common code
  2014. SHPRO    ENDP
  2015.  
  2016. SHSCPT    PROC    NEAR            ; Show Script
  2017.     mov    ah,cmeol
  2018.     call    comnd            ; get a confirm
  2019.     jnc    shscpt1            ; nc = success
  2020.     ret                ; failure
  2021. shscpt1:mov    dx,offset crlf
  2022.     mov    ah,prstr
  2023.     int    dos            ; print a crlf
  2024.     mov    bx,offset stscpt    ; table of items to be shown
  2025.     jmp    statc            ; finish in common code
  2026. SHSCPT    ENDP
  2027.  
  2028. SHSERV    PROC    NEAR            ; Show Server
  2029.     mov    ah,cmeol
  2030.     call    comnd            ; get a confirm
  2031.     jnc    shserv1            ; nc = success
  2032.     ret                ; failure
  2033. shserv1:mov    dx,offset crlf
  2034.     mov    ah,prstr
  2035.     int    dos            ; print a crlf
  2036.     mov    bx,offset stserv2    ; do timeout item
  2037.     call    statc
  2038.     mov    dx,offset crlf
  2039.     mov    ah,prstr
  2040.     int    dos
  2041.     mov    bx,offset stserv    ; table of items to be shown
  2042.     jmp    statc            ; finish in common code
  2043. SHSERV    ENDP
  2044.  
  2045. SHTERM    PROC    NEAR            ; Show Terminal
  2046.     mov    ah,cmeol
  2047.     call    comnd            ; get a confirm
  2048.     jnc    shterm1            ; nc = success
  2049.     ret                ; failure
  2050. shterm1:mov    dx,offset crlf
  2051.     mov    ah,prstr
  2052.     int    dos            ; print a crlf
  2053.     mov    bx,offset stterm    ; table of items to be shown
  2054.     jmp    statc            ; use common code
  2055. SHTERM    ENDP
  2056.  
  2057. ; SHOW VAR of kind \v(name)
  2058. SHOVAR    proc    near
  2059.     mov    ah,cmword
  2060.     mov    dx,offset rdbuf
  2061.     mov    bx,offset shvmsg
  2062.     mov    comand.cmper,1        ; don't react to \%x variables
  2063.     call    comnd
  2064.     jnc    shovar1            ; nc = success
  2065.     ret                ; failure
  2066. shovar1:mov    shmcnt,ax        ; save length of user spec
  2067.     mov    ah,cmeol
  2068.     call    comnd
  2069.     jnc    shovar2            ; nc = success
  2070.     ret                ; failure
  2071. shovar2:call    fshovar            ; call FAR worker
  2072.     ret
  2073. SHOVAR    endp
  2074.  
  2075. begtim    proc    near
  2076.     call    fbegtim            ; call the real FAR routine
  2077.     ret
  2078. begtim    endp
  2079. endtim    proc    near
  2080.     call    fendtim            ; call the real FAR routine
  2081.     ret
  2082. endtim    endp
  2083.  
  2084. ; SHOW STATISTICS command. Displays last operation and session statistics
  2085. shosta    proc    near            ; show file transfer statistics
  2086.     mov    ah,cmeol        ; confirm with carriage return
  2087.     call    comnd
  2088.     jnc    shosta1
  2089.     ret                ; failure
  2090. shosta1:xor    ax,ax
  2091.     call    endtim            ; update statistics, just in case
  2092.     call    fshosta            ; do a far call to worker
  2093.     ret
  2094. shosta    endp
  2095.  
  2096. ; STATUS command
  2097.  
  2098. STATUS    PROC    NEAR
  2099.     mov    ah,cmeol
  2100.     call    comnd            ; get a confirm
  2101.     jnc    stat0a            ; nc = success
  2102.     ret                ; failure
  2103. stat0a:    mov    dx,offset crlf
  2104.     mov    ah,prstr
  2105.     int    dos            ; print a crlf
  2106.                     ; STAT0 is an external ref (in mster)
  2107. STAT0:    call    cmblnk            ; clear the screen
  2108.     call    locate            ; home the cursor
  2109.     mov    bx,offset sttab        ; table to control printing
  2110.     xor    cx,cx            ; column counter
  2111.                     ; STATC is external ref in msx
  2112. STATC:    cmp    word ptr [bx],0        ; end of table?
  2113.     je    statx            ; e = yes
  2114.     cld                ; string direction is forward
  2115.     push    ds
  2116.     pop    es
  2117.     mov    di,offset rdbuf        ; point to destination buffer
  2118.     mov    byte ptr[di],spc    ; start with two spaces
  2119.     inc    di
  2120.     mov    byte ptr[di],spc
  2121.     inc    di
  2122.     push    cx            ; save column number
  2123.     push    bx
  2124.     call    [bx].sttyp        ; call appropriate routine
  2125.     pop    bx
  2126.     pop    cx
  2127.     sub    di,offset rdbuf        ; number of bytes used
  2128.     add    cx,di            ; new line col count
  2129.     push    cx            ; save col number around print
  2130.     mov    cx,di            ; how much to print now
  2131.     mov    di,offset rdbuf        ; source text
  2132.     cmp    cx,2            ; nothing besides our two spaces?
  2133.     jbe    stat5            ; e = yes, forget it
  2134.     call    prtscr            ; print counted string
  2135. stat5:    pop    cx
  2136.     add    bx,size stent        ; look at next entry
  2137.     cmp    word ptr [bx],0        ; at end of table?
  2138.     je    statx            ; e = yes
  2139.     cmp    cx,38            ; place for second display?
  2140.     jbe    stat2            ; be = only half full
  2141.     mov    dx,offset crlf        ; over half full. send cr/lf
  2142.     mov    ah,prstr
  2143.     int    dos
  2144.     xor    cx,cx            ; say line is empty now
  2145.     jmp    statc
  2146. stat2:    mov    ax,cx
  2147.     mov    cx,38            ; where we want to be next time
  2148.     sub    cx,ax            ; compute number of filler spaces
  2149.     or    cx,cx
  2150.     jle    stat4            ; nothing to do
  2151.     mov    ah,conout
  2152.     mov    dl,' '
  2153. stat3:    int    dos            ; fill with spaces
  2154.     loop    stat3            ; do cx times
  2155. stat4:    mov    cx,38            ; current column number
  2156.     jmp    statc            ; and do it
  2157. statx:    clc
  2158.     ret
  2159. STATUS    ENDP
  2160.  
  2161. ; handler routines for status
  2162. ; all are called with di/ destination buffer, bx/ stat ptr. They can change
  2163. ; any register except es:, must update di to the end of the buffer.
  2164.  
  2165.  
  2166. ; Copy dollar sign terminated string to buffer pointed at by preset di.
  2167. stmsg    proc    near
  2168.     push    ds
  2169.     pop    es        ; ensure es points to data segment
  2170.     mov    si,[bx].msg    ; get message address
  2171. stms1:    lodsb            ; get a byte
  2172.     stosb            ; drop it off
  2173.     or    al,al        ; ending on null?
  2174.     jz    stms2        ; z = yes
  2175.     cmp    al,'$'        ; end of message?
  2176.     jne    stms1        ; no, keep going
  2177. stms2:    dec    di        ; else back up ptr
  2178.     ret
  2179. stmsg    endp
  2180.  
  2181. ; get address of test value in stent. Returns address in si
  2182. stval    proc    near
  2183.     mov    si,[bx].basval    ; get base value
  2184.     or    si,si        ; any there?
  2185.     jz    stva1        ; z = no, keep going
  2186.     mov    si,[si]        ; yes, use as base address
  2187. stva1:    add    si,[bx].tstcel    ; add offset of test cell
  2188.     ret            ; and return it
  2189. stval    endp
  2190.  
  2191. ; print a single character
  2192. onechr    proc    near
  2193.     call    stmsg        ; copy message part first
  2194.     call    stval        ; pick up test value address
  2195.     mov    al,[si]        ; this is char to print
  2196.     cmp    al,7fh        ; in graphics region?
  2197.     jb    onech2        ; b = no
  2198.     mov    byte ptr [di],'\' ; do in \numerical form
  2199.     inc    di
  2200.     xor    ah,ah        ; clear high byte
  2201.     jmp    outnum        ; do number part
  2202. onech2:    cmp    al,' '        ; printable?
  2203.     jae    onech1        ; yes, keep going
  2204.     add    al,64        ; make printable
  2205.     mov    byte ptr [di],5eh    ; caret
  2206.     inc    di        ; note ctrl char
  2207. onech1:    stosb            ; drop char off
  2208.     ret
  2209. onechr    endp
  2210.  
  2211. ; numeric field
  2212. stnum    proc    near        ; for 8 bit numbers
  2213.     call    stmsg        ; copy message
  2214.     call    stval        ; pick up value address
  2215.     mov    al,[si]        ; get value
  2216.     xor    ah,ah        ; high order is 0
  2217.     jmp    outnum        ; put number into buffer
  2218. stnum    endp
  2219.  
  2220. stlnum    proc    near        ; for 16 bit numbers
  2221.     call    stmsg        ; copy message
  2222.     call    stval        ; pick up value address
  2223.     mov    ax,[si]        ; get value
  2224.     jmp    outnum        ; put number into buffer
  2225. stlnum    endp
  2226.  
  2227. ; translate the number in ax
  2228. outnum    proc    near
  2229.     xor    dx,dx
  2230.     mov    bx,10
  2231.     div    bx        ; divide to get digit
  2232.     push    dx        ; save remainder digit
  2233.     or    ax,ax        ; test quotient
  2234.     jz    outnu1        ; zero, no more of number
  2235.     call    outnum        ; else call for rest of number
  2236. outnu1:    pop    ax        ; get digit back
  2237.     add    al,'0'        ; make printable
  2238.     stosb            ; drop it off
  2239.     ret
  2240. outnum    endp
  2241.  
  2242. ; on/off field
  2243. onoff    proc    near
  2244.     call    stmsg        ; copy message
  2245.     call    stval        ; get value cell
  2246.     mov    al,[si]
  2247.     mov    si,offset onmsg
  2248.     mov    cx,2        ; assume 2-byte 'ON' message
  2249.     or    al,al        ; test value
  2250.     jnz    onof1        ; on, have right msg
  2251.     mov    si,offset offmsg
  2252.     mov    cx,3
  2253. onof1:    cld
  2254.     push    ds
  2255.     pop    es
  2256.     rep    movsb        ; copy right message in
  2257.     ret
  2258. onoff    endp
  2259.  
  2260. ; print first message if false, second if true
  2261. msg2    proc    near
  2262.     call    stval        ; get value cell
  2263.     mov    al,[si]
  2264.     mov    si,[bx].msg    ; assume off
  2265.     or    al,al        ; is it?
  2266.     jz    msg21        ; yes, continue
  2267.     mov    si,[bx].val2    ; else use alternate message
  2268. msg21:    jmp    stms1        ; handle copy and return
  2269. msg2    endp
  2270.  
  2271. ; print first message if false, second if true, uses bit in byte for value
  2272. msg2b    proc    near
  2273.     call    stbval        ; get bit value cell
  2274.     mov    si,[bx].msg    ; assume off
  2275.     or    al,al        ; is it?
  2276.     jz    msg2b1        ; yes, continue
  2277.     mov    si,[bx].val2    ; else use alternate message
  2278. msg2b1:    jmp    stms1        ; handle copy and return
  2279. msg2b    endp
  2280.  
  2281. ; search a keyword table for a word value, print that value
  2282. srchkww    proc    near
  2283.     call    stmsg        ; copy the first message
  2284.     call    stval
  2285.     mov    ax,[si]        ; get value to hunt for
  2286.     mov    bx,[bx].val2    ; this is table address
  2287.     jmp    prttab        ; and look in table
  2288. srchkww    endp
  2289.  
  2290. ; search a keyword table for a byte value, print that value
  2291. srchkw    proc    near
  2292.     call    stmsg        ; first print message
  2293.     call    stval
  2294.     mov    al,[si]        ; get value to hunt for
  2295.     xor    ah,ah        ; high order is 0
  2296.     mov    bx,[bx].val2    ; this is table address
  2297.     jmp    prttab        ; and look in table
  2298. srchkw    endp
  2299.  
  2300. ; search a keyword table for a bit value, print that value
  2301. srchkb    proc    near
  2302.     call    stmsg            ; first print message
  2303.     call    stbval            ; get bit set or reset
  2304.     mov    bx,[bx].val2        ; this is table address
  2305.     jmp    prttab            ; and look in table
  2306. srchkb    endp
  2307.  
  2308. ; get address of test value in stent.  Returns address in si.
  2309. stbval    proc    near
  2310.     mov    si,[bx].basval        ; get address of test value
  2311.     or    si,si            ; any there?
  2312.     jz    stbva1            ; z = no, quit with no match
  2313.     mov    ax,[si]            ; get value
  2314.     test    ax,[bx].tstcel         ; bit test value against data word
  2315.     jz    stbva1            ; z = they don't match
  2316.     mov    ax,1            ;  match
  2317.     ret
  2318. stbva1:    xor    ax,ax            ; no match
  2319.     ret                ; and return it
  2320. stbval    endp
  2321.  
  2322.  
  2323. ; Print the drive name
  2324. drnum    proc    near
  2325.     call    stmsg        ; copy message part first
  2326.     call    stval        ; pick up test value address
  2327.     mov    ah,gcurdsk    ; Get current disk
  2328.     int    dos
  2329.     inc    al        ; We want 1 == A (not zero)
  2330.     mov    curdsk,al
  2331.     add    al,'@'        ; Make it printable
  2332.     cld
  2333.     push    ds
  2334.     pop    es
  2335.     stosb
  2336.     mov    word ptr [di],'\:'
  2337.     add    di,2        ; end with a colon and backslash
  2338.     mov    byte ptr [di],0    ; terminate in case drive is not ready
  2339.     xor    dl,dl        ; get current drive
  2340.     mov    ah,gcd        ; get current directory
  2341.     mov    si,di        ; current working buffer position
  2342.     int    dos
  2343.     push    cx
  2344.     push    dx
  2345.     mov    dx,di        ; directory string
  2346.     call    strlen        ; length of path part to cx
  2347.     cmp    cx,26        ; too long to show the whole thing?
  2348.     jbe    drnum3        ; be = is ok, show the whole path
  2349.     push    di        ; scan backward for last backslash
  2350.     mov    al,'\'        ; thing to search for
  2351.     std            ; backward
  2352.     mov    di,si        ; start of buffer
  2353.     add    di,cx        ; length of string
  2354.     repne    scasb        ; scan backward for a backslash
  2355.     jcxz    drnum2        ; should not happen, but then again 
  2356.     repne    scasb        ; do again for second to last path part
  2357. drnum2:    cld            ; reset direction flag
  2358.     dec    di        ; move di two places preceding backslash
  2359.     mov    [di],'--'    ; insert a missing path indicator
  2360.     dec    di
  2361.     mov    byte ptr [di],'-'
  2362.     mov    si,di        ; we will show just this part
  2363.     pop    di        ; recover main status pointer
  2364. drnum3:    pop    dx
  2365.     pop    cx
  2366.     
  2367. drnum4:    lodsb            ; copy until null terminator
  2368.     stosb
  2369.     or    al,al        ; end of string?
  2370.     jnz    drnum4        ; nz = no
  2371.     dec    di        ; offset inc of stosb
  2372.     ret
  2373. drnum    endp
  2374.  
  2375.  
  2376. ; Print the screen-dump filename [jrd]
  2377.  
  2378. pasz    proc    near
  2379.     call    stmsg        ; copy message part
  2380.     mov    si,[bx].val2    ; address of asciiz string
  2381.     push    ds
  2382.     pop    es
  2383.     cld
  2384. pasz1:    lodsb            ; get a byte
  2385.     or    al,al        ; at end yet?
  2386.     jz    pasz2        ; z = yes
  2387.     stosb            ; store in buffer
  2388.     jmp    short pasz1    ; keep storing non-null chars
  2389. pasz2:    ret
  2390. pasz    endp
  2391.  
  2392. ; Display Send and Receive chars
  2393. prsar    proc    near
  2394.     call     stmsg        ; display leadin part of message
  2395.     push    ds
  2396.     pop    es
  2397.     cld
  2398.     mov    si,[bx].tstcel    ; get address of first item
  2399.     mov    al,[si]
  2400.     cmp    al,7fh        ; DEL code?
  2401.     jne    prsar1        ; ne = no
  2402.     mov    ax,'1\'        ; say \127
  2403.     cmp    byte ptr [di-1],5eh ; caret present in msg?
  2404.     jne    prsar5        ; ne = no
  2405.     dec    di        ; remove "^"
  2406. prsar5:    stosw
  2407.     mov    ax,'72'
  2408.     stosw
  2409.     jmp    short prsar2
  2410. prsar1:    dec    di        ; remove "^"
  2411.     cmp    al,20h        ; printable now?
  2412.     jae    prsar7        ; ae = yes
  2413.     inc    di        ; restore "^"
  2414.     add    al,40H        ; make it printable
  2415. prsar7:    stosb
  2416. prsar2:    mov    si,[bx].val2    ; get address of second msg
  2417.     call    stms1        ; add that
  2418.     mov    si,[bx].basval    ; second value's address
  2419.     mov    al,[si]        ; second value
  2420.     cmp    al,7fh        ; DEL code?
  2421.     jne    prsar3        ; ne = no
  2422.     mov    ax,'1\'        ; say \127
  2423.     cmp    byte ptr [di-1],5eh ; caret present in msg?
  2424.     jne    prsar6        ; ne = no
  2425.     dec    di        ; remove "^"
  2426. prsar6:    stosw
  2427.     mov    ax,'72'
  2428.     stosw
  2429.     ret
  2430. prsar3:    dec    di        ; remove "^"
  2431.     cmp    al,20h        ; printable now?
  2432.     jae    prsar3a        ; ae = yes
  2433.     inc    di        ; restore "^"
  2434.     add    al,40H        ; make it printable
  2435. prsar3a:stosb
  2436.     ret
  2437. prsar    endp
  2438.  
  2439. ; Display Send and Receive char value
  2440. prsarv    proc    near
  2441.     call     stmsg        ; display leadin part of message
  2442.     mov    si,[bx].tstcel    ; get address of first item
  2443.     mov    al,[si]
  2444.     xor    ah,ah
  2445.     push    bx
  2446.     call    outnum
  2447.     pop    bx
  2448.     mov    si,[bx].val2    ; get address of second msg
  2449.     call    stms1        ; add that
  2450.     mov    si,[bx].basval    ; second value's address
  2451.     mov    al,[si]        ; second value
  2452.     xor    ah,ah
  2453.     jmp    outnum
  2454. prsarv    endp
  2455.  
  2456.  
  2457. ; print Send Delay and Pause
  2458. prsnd    proc    near
  2459.     call    stmsg        ; display leadin part of msg
  2460.     mov    al,trans.sdelay    ; Send Delay (sec)
  2461.     xor    ah,ah
  2462.     call    outnum
  2463.     mov    si,offset sndmsg2 ; second part of msg
  2464.     call    stms1        ; add that
  2465.     mov    al,spause    ; Send Pause (millisec) 
  2466.     call    outnum
  2467.     mov    si,offset sndmsg3 ; last part of msg
  2468.     jmp    stms1        ; add it too
  2469. prsnd    endp
  2470.  
  2471. ; Print the handshake
  2472. prhnd:    mov    si,offset handst    ; copy in initial message
  2473.     call    stms1
  2474.     mov    si,offset nonmsg    ; assume no handshake
  2475.     mov    bx,portval
  2476.     cmp    [bx].hndflg,0        ; Is handshaking in effect?
  2477.     jne    prh0            ; Yes, print what we're using
  2478.     jmp    stms1            ; no, say so and return
  2479. prh0:    mov    al,5eh            ; Doing handshaking with control char
  2480.     push    ds
  2481.     pop    es
  2482.     cld
  2483.     stosb
  2484.     mov    al,[bx].hands
  2485.     add    al,40H            ; Make printable
  2486.     stosb                ; put in buffer
  2487.     ret
  2488.  
  2489. ; Print the Transmit Fill char
  2490. prfil:    mov    si,offset sxfilmsg    ; copy in initial message
  2491.     call    stms1
  2492.     mov    si,offset nonmsg    ; assume no handshake
  2493.     mov    al,script.xmitfill    ; filling char
  2494.     or    al,al            ; is filling in effect?
  2495.     jnz    prfil1            ; nz = yes, print what we're using
  2496.     jmp    stms1            ; no, say so and return
  2497. prfil1:    push    ds
  2498.     pop    es
  2499.     cld
  2500.     cmp    al,20h            ; printable already?
  2501.     ja    prfil2            ; a = yes
  2502.     push    ax
  2503.     mov    al,5eh            ; control char
  2504.     stosb
  2505.     pop    ax
  2506.     add    al,40H            ; make printable
  2507.     stosb                ; put in buffer
  2508.     ret                ; and return
  2509. prfil2:    cmp    al,126            ; in ordinary printable range?
  2510.     ja    prfil3            ; a = no
  2511.     stosb                ; store in buffer
  2512.     ret
  2513. prfil3:    mov    byte ptr [di],'\'    ; show as \number
  2514.     inc    di
  2515.     xor    ah,ah
  2516.     jmp    outnum            ; do rest of number
  2517.  
  2518. ; Print value from table.  BX is address of table, AX is value of variable
  2519. ; Copy value of table text entry to output buffer (di), given the address
  2520. ; of the table in bx and the value to compare against table values in al.
  2521. prttab    proc    near
  2522.     push    cx            ; save column count
  2523.     mov    cl,[bx]            ; number of entries in our table
  2524.     inc    bx            ; point to the data
  2525. prtta1:    mov    si,[bx]            ; length of keyword
  2526.     cmp    ax,[bx+si+2]        ; value fields match?
  2527.     je    prtta2            ; e = yes
  2528.     add    bx,si            ; add word length
  2529.     add    bx,4            ; skip count and value fields
  2530.     dec    cl            ; more keywords to check?
  2531.     jnz    prtta1            ; nz = yes, go to it
  2532.     pop    cx
  2533.     mov    si,offset prterr
  2534.     jmp    stms1            ; copy dollar terminated string
  2535. prtta2:    push    ds
  2536.     pop    es        ; ensure es points to data segment
  2537.     mov    cx,[bx]        ; get length of counted string
  2538.     push    cx        ; save
  2539.     mov    si,bx
  2540.     add    si,2        ; look at text
  2541.     cld
  2542.     rep    movsb
  2543.     pop    ax
  2544.     pop    cx        ; original cx
  2545.     add    cx,ax        ; advance column count, return di advanced
  2546.     ret
  2547. prttab    endp
  2548.  
  2549. ; Display port speed
  2550.  
  2551. BAUDPRT    PROC     NEAR
  2552.     mov    si,offset baudrt    ; "Speed: "
  2553.     call    stms1            ; display that part
  2554.     push    di
  2555.     push    cx
  2556.     call    getbaud            ; read baud rate first
  2557.     pop    cx
  2558.     pop    di
  2559.     mov    bx,portval
  2560.     mov    ax,[bx].baud
  2561.     cmp    al,byte ptr bdtab    ; number of table entries
  2562.     jb    bdprt5            ; b = in table
  2563.     mov    si,offset unrec        ; say unrecognized value
  2564.     jmp    stms1            ; display text and return
  2565. bdprt5:    mov    bx,offset bdtab        ; show ascii rate from table
  2566.     jmp    prttab
  2567. BAUDPRT    ENDP
  2568.  
  2569. ; display Take/Macro COUNT
  2570. stcnt    proc    near
  2571.     call    stmsg            ; display leadin part of msg
  2572.     cmp    taklev,0        ; in a Take file or macro?
  2573.     jne    stcnt1            ; ne = yes
  2574.     mov    si,offset nonemsg    ; say none
  2575.     jmp    stms1
  2576. stcnt1:    push    bx
  2577.     mov    bx,takadr        ; current Take structure
  2578.     mov    ax,[bx].takctr        ; get COUNT
  2579.     pop    bx
  2580.     jmp    outnum
  2581. stcnt    endp
  2582.  
  2583. ; display Take/Macro ARGC
  2584. starg    proc    near
  2585.     call    stmsg            ; display leadin part of msg
  2586.     cmp    taklev,0        ; in a Take file or macro?
  2587.     jne    starg1            ; ne = yes
  2588.     mov    si,offset nonemsg    ; say none
  2589.     jmp    stms1
  2590. starg1:    push    bx
  2591.     mov    bx,takadr        ; current Take structure
  2592.     mov    ax,[bx].takargc        ; get ARGC
  2593.     pop    bx
  2594.     jmp    outnum
  2595. starg    endp
  2596.  
  2597. ; ALARM time
  2598. stalr    proc    near
  2599.     call    stmsg            ; display leading part of msg
  2600.     push    bx            ; preserve register
  2601.     xor    bx,bx            ; position index
  2602.     push    ds
  2603.     pop    es
  2604.     cld
  2605. stalr1:    push    bx            ; save around calls
  2606.     cmp    alrhms[bx],10        ; two digits?
  2607.     jae    stalr2            ; ae = yes
  2608.     mov    al,'0'
  2609.     stosb                ; show leading zero
  2610. stalr2:    mov    al,alrhms[bx]        ; show time component
  2611.     xor    ah,ah
  2612.     call    outnum
  2613.     pop    bx            ; recover index
  2614.     inc    bx
  2615.     cmp    bx,3            ; done all fields?
  2616.     jae    stalr3            ; ae = yes
  2617.     mov    al,':'
  2618.     stosb
  2619.     jmp    short stalr1        ; do next field
  2620. stalr3:    pop    bx
  2621.     ret
  2622. stalr    endp
  2623.  
  2624. ; show INPUT buffer
  2625. stinbuf    proc    near
  2626.     push    si
  2627.     push    di
  2628.     push    es
  2629.     mov    di,offset rdbuf
  2630.     mov    byte ptr [di],cr    ; start on the margin
  2631.     inc    di
  2632.     push    di
  2633.     call    buflog            ; get INPUT buffer pointers
  2634.     pop    di
  2635.     mov    bx,cx            ; length of buffer (and max offset)
  2636.     mov    byte ptr [di],'<'    ; start with "<# unread chars>"
  2637.     inc    di
  2638.     push    cx
  2639.     push    dx
  2640.     call    dec2di            ; ax has unread count, bufcnt
  2641.     pop    dx
  2642.     pop    cx
  2643.     mov    byte ptr [di],'>'
  2644.     inc    di
  2645. stinb1:    mov    al,es:[si]        ; extract a buffer char into al
  2646.     inc    si            ; move pointer to next byte
  2647.     test    al,80h            ; high bit set?
  2648.     jz    stinb2            ; z = no
  2649.     mov    byte ptr [di],'~'    ; yes, show a tilde
  2650.     inc    di
  2651. stinb2:    and    al,7fh            ; strip eighth bit
  2652.     cmp    al,' '            ; control code?
  2653.     jae    stinb3            ; ae = no
  2654.     mov    byte ptr [di],'^'    ; yes, show caret
  2655.     inc    di
  2656.     or    al,40h            ; convert char to upper case letter
  2657. stinb3:    mov    [di],al
  2658.     inc    di            ; where to write next byte
  2659.     cmp    di,offset rdbuf+78    ; line full?
  2660.     jb    stinb4            ; b = no, have more room
  2661.     mov    word ptr [di],0a0dh    ; add cr/lf
  2662.     mov    byte ptr [di+2],0
  2663.     mov    dx,offset rdbuf
  2664.     mov    di,dx
  2665.     call    prtasz
  2666. stinb4:    cmp    si,bx            ; beyond end of Input buffer?
  2667.     jb    stinb5            ; b = not yet
  2668.     xor    si,si            ; reset to start of INPUT-buf (wrap)
  2669. stinb5:    loop    stinb1
  2670.     mov    word ptr [di],0a0dh    ; add cr/lf
  2671.     mov    byte ptr [di+2],0
  2672.     mov    dx,offset rdbuf        ; reset to start of our local buffer
  2673.     mov    di,dx
  2674.     call    prtasz
  2675.     pop    es
  2676.     pop    di
  2677.     pop    si
  2678.     xor    cx,cx
  2679.     ret
  2680. stinbuf    endp
  2681.  
  2682. ; LNOUT - Table driven unsigned long integer (32 bit) display
  2683. ; Register dx holds high order word and ax holds low order word of unsigned
  2684. ; long integer to be stored in decimal. Storage area is given by DS:[DI]
  2685. ; DI is incremented for each storage, null terminated.
  2686. ; Table TENS holds set of double word values of ten raised to powers 0 to 9
  2687. ; TENSLEN holds the number of these double words
  2688. ; All registers preserved.    8 March 1987 [jrd]
  2689.  
  2690. lnouts    proc    near            ; do lnout with thousands separator
  2691.     push    ax
  2692.     mov    al,thsep        ; get thousands separator
  2693.     mov    lnoutsep,al        ; tell lnout to use it
  2694.     pop    ax
  2695.     call    lnout            ; compute value to di
  2696.     mov    lnoutsep,0        ; clear for future callers
  2697.     ret
  2698. lnouts    endp
  2699.  
  2700. lnout    proc    near
  2701.     push    ax
  2702.     push    bx
  2703.     push    cx
  2704.     push    dx
  2705.     push    si
  2706.     xor    si,si        ; flag to say start printing (no leading 0's)
  2707.     mov    cx,tenslen    ; number of table entries
  2708. lnout1:    push    cx        ; save loop counter
  2709.     mov    bx,cx        ; index into tens double word table
  2710.     dec    bx        ; index starts at zero
  2711.     add    bx,bx
  2712.     add    bx,bx        ; bx times four (double words to bytes)
  2713.     xor    cx,cx        ; cx is now a counter of subtractions
  2714.  
  2715. lnout2:    cmp    dx,word ptr tens[bx+2]  ; pattern 10**(bx/4), high order part
  2716.     jb    lnout4        ; b = present number is less than pattern
  2717.     ja    lnout3        ; a = present number is larger than pattern
  2718.     cmp    ax,word ptr tens[bx] ; high words match, how about lows
  2719.     jb    lnout4        ; b = present number is smaller than pattern
  2720. lnout3:    sub    ax,word ptr tens[bx]    ; subtract low order words
  2721.     sbb    dx,word ptr tens[bx+2]    ; subtract high order words, w/borrow
  2722.     inc    cl        ; count number of subtractions
  2723.     inc    si        ; flag to indicate printing needed
  2724.     jmp    short lnout2    ; try again to deduct present test pattern
  2725.  
  2726. lnout4:    or    bx,bx        ; doing least significant digit?
  2727.     jz    lnout5        ; z = yes, always print this one
  2728.     or    si,si        ; should we print?
  2729.     jz    lnout6        ; z = no, not yet
  2730. lnout5:    add    cl,'0'        ; get number of subtractions
  2731.     mov    [di],cx        ; store it (ch is still zero), asciiz
  2732.     inc    di
  2733.     cmp    bx,9*4        ; places for thousands separator?
  2734.     je    lnout5a        ; e = yes
  2735.     cmp    bx,6*4
  2736.     je    lnout5a
  2737.     cmp    bx,3*4
  2738.     jne    lnout6        ; ne = no
  2739. lnout5a:mov    cl,lnoutsep    ; get thousands separator
  2740.     jcxz    lnout6        ; z = none
  2741.      mov    word ptr [di],cx
  2742.     inc    di
  2743. lnout6:    pop    cx        ; recover loop counter
  2744.     loop    lnout1
  2745.     pop    si
  2746.     pop    dx
  2747.     pop    cx
  2748.     pop    bx
  2749.     pop    ax
  2750.     ret
  2751. lnout    endp 
  2752.  
  2753. code    ends
  2754.     end
  2755.