home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / extra / nyenhuis3.arc / MSSTER.ASM < prev    next >
Assembly Source File  |  1990-01-14  |  35KB  |  1,192 lines

  1.      NAME    msster
  2. ; File MSSTER.ASM
  3.     include mssdef.h
  4. ; Last edit 14 Jan 1990
  5.  
  6.     public    clscpt, defkey, clscpi, ploghnd, sloghnd, tloghnd
  7.     public  dopar, shokey, cptchr, pktcpt, targ, replay, repflg
  8.     public    kbdflg, shkadr, telnet, ttyact, write, dec2di
  9.     public    cnvlin, katoi, decout, valout, atoi, cnvstr
  10.  
  11. braceop    equ    7bh            ; opening curly brace
  12. bracecl    equ    7dh            ; closing curly brace
  13.  
  14. data     segment    public 'data'
  15.     extrn    flags:byte, trans:byte, portval:word, taklev:byte, takadr:word
  16.     extrn    comand:byte, verident:byte, rdbuf:byte, errlev:byte
  17.     extrn    dosnum:word, diskio:byte
  18.  
  19. targ    termarg    <0,1,cptchr,0,parnon>
  20. crlf    db      cr,lf,'$'
  21. tmsg1    db    cr,lf,'(Connecting to host, type $' 
  22. tmsg3    db    ' C to return to PC)',cr,lf,cr,lf,cr,lf,'$'
  23. erms25    db    cr,lf,'?Input must be numeric$' 
  24. erms22    db    cr,lf,'?No open logging file$'
  25. erms23    db    cr,lf,'?Error writing session log, suspending capture.'
  26.     db    cr,lf,'$'
  27. erms24    db    cr,lf,'?Error writing Packet log$'
  28. esctl    db    'Control-$'
  29. repflg    db    0        ; REPLAY or SET TERM REPLAY filespec flag
  30. rephlp    db    'name of file to playback$'
  31. reperr    db    cr,lf,'?File not found$'    ; for REPLAY command
  32. msgtxt    db    'optional text, if any$'
  33.  
  34. inthlp db cr,lf,'  ?  This message                    F  Dump screen to file'
  35.        db cr,lf,'  C  Close the connection            P  Push to DOS'
  36.        db cr,lf,'  S  Status of the connection        Q  Quit logging'
  37.        db cr,lf,'  M  Toggle mode line                R  Resume logging'
  38.        db cr,lf,'  B  Send a Break                    0  Send a null'
  39.        db cr,lf,'  L  Send a long 1.8 s Break         H  Hangup phone'
  40.        db cr,lf,'  Typing the escape character will send it to the host'
  41.        db 0          ; this short-form obscures less screen area [jrd]
  42.  
  43. intprm    db    'Command> $'
  44. intclet    db    'B','C','F','H','L'    ; single letter commands
  45.     db    'M','P','Q','R','S'    ; must parallel dispatch table intcjmp
  46.     db    '?','0'
  47. numlet    equ    $ - intclet        ; number of entries
  48.     even
  49. intcjmp    dw    intchb,intchc,intchf,intchh,intchl
  50.     dw    intchm,intchp,intchq,intchr,intchs
  51.     dw    intchu,intchn
  52.  
  53. pktbuf    db    cptsiz dup (?)    ; packet logging buffer
  54. pktbp    dw    pktbuf        ; buffer pointer to next free byte
  55. pktlft    dw    cptsiz        ; number free bytes left
  56. capbuf    db    cptsiz dup (?)    ; session logging buffer
  57. capbp    dw    capbuf        ; buffer pointer to next free byte
  58. caplft    dw    cptsiz        ; number free bytes left
  59.     even
  60. ploghnd    dw    -1        ; packet logging handle
  61. sloghnd    dw    -1        ; session logging handle
  62. tloghnd    dw    -1        ; transaction logging handle
  63.  
  64. clotab    db    4
  65.     mkeyw    'All',logpkt+logses+logtrn
  66.     mkeyw    'Packets',logpkt
  67.     mkeyw    'Session',logses
  68.     mkeyw    'Transaction',logtrn
  69.  
  70. clseslog db    cr,lf,' Closing Session log$'
  71. clpktlog db    cr,lf,' Closing Packet log$'
  72. cltrnlog db    cr,lf,' Closing Transaction log$'
  73. clohlp    db    cr,lf,' One of the following log files:'
  74.     db    cr,lf,' ALL, Packets, Session, Transaction$'
  75.  
  76. writetab db    4            ; Write command log file types
  77.     mkeyw    'Packet',logpkt
  78.     mkeyw    'Screen',80h        ; unused value, to say screen
  79.     mkeyw    'Session',logses
  80.     mkeyw    'Transaction',logtrn
  81.  
  82. wrtobj    db    9            ; table of objects to be written
  83.     mkeyw    'ARGC',wrtargc        ; Argument count
  84.     mkeyw    'COUNT',wrtcnt        ; loop COUNT
  85.     mkeyw    'Date',wrtdate        ; DOS date
  86.     mkeyw    'Errorlevel',wrterr    ; Errorlevel
  87.     mkeyw    'INPUT-buffer',wrtinp    ; Input command's circular buffer
  88.     mkeyw    'Path',wrtpath        ; current DOS path
  89.     mkeyw    'Text',wrttxt        ; text
  90.     mkeyw    'Time',wrttime        ; DOS time of day
  91.     mkeyw    'Version',wrtver    ; version of MS Kermit
  92.  
  93. sttmsg    db    cr,lf,'Press space to continue ...$'
  94. kbdflg    db    0            ; non-zero means char here from Term
  95. ttyact    db    0            ; Connect mode active, if non-zero
  96. shkadr    dw    0            ; offset of replacement Show Key cmd
  97. ten    dw    10            ; multiplier for setatoi
  98. nbase    dw    ?            ; currently active number base
  99. numset    db    '0123456789ABCDEF'    ; number conversion alphabet
  100. temp    dw    0
  101. tmp    db    0
  102. data    ends
  103.  
  104. code    segment    public 'code'
  105.     extrn     comnd:near, outchr:near, stat0:near, iseof:near
  106.     extrn    term:near, strlen:near, buflog:near
  107.     extrn    beep:near, puthlp:near, getbaud:near, serhng:near
  108.     extrn    serini:near,serrst:near, sendbr:near
  109.     extrn    fpush:near, dumpscr:near, sendbl:near
  110.     assume    cs:code, ds:data, es:nothing
  111.  
  112. ; the show key command
  113. shokey    proc    near
  114.     cmp    shkadr,0        ; keyboard translator present?
  115.     je    shokey1            ; e = no, use regular routines
  116.     mov    bx,shkadr        ; get offset of replacement routine
  117.     jmp    bx            ; and execute it rather than us
  118. shokey1:clc
  119.     ret
  120. shokey    endp
  121. ; enter with ax/scan code to define, si/ pointer to definition, cx/ length
  122. ; of definition.  Defines it in definition table. Obsolete.
  123. defkey    proc    near
  124.     ret
  125. defkey    endp
  126.  
  127. ; This is the CONNECT command
  128.  
  129. TELNET     PROC    NEAR
  130.     mov    ah,cmeol
  131.     call    comnd            ; get a confirm
  132.     jnc    teln2            ; nc = success
  133.     ret
  134. teln2:    mov    ah,prstr
  135.     mov    dx,offset crlf        ; output a crlf
  136.     int    dos
  137.     cmp    flags.vtflg,0        ; emulating a terminal?
  138.     jne    teln1            ; ne= yes, skip    flashing message
  139.     call    domsg            ; Reassure user
  140. teln1:    call    serini            ; ensure port is inited now
  141.     mov    al,0            ; initial flags
  142.     mov    ttyact,1        ; say telnet is active
  143.     cmp    flags.vtflg,0        ; emulating a terminal?
  144.     je    teln3            ; e = no, say mode line is to be off
  145.     cmp    flags.modflg,0        ; mode line enabled?
  146.     jne    tel010            ; ne = yes
  147. teln3:    or    al,modoff        ; no, make sure it stays off
  148.  
  149. tel010:    test    flags.debug,logses    ; debug mode?
  150.     jz    tel0            ; z = no, keep going
  151.     or    al,trnctl        ; yes, show control chars
  152. tel0:    cmp    flags.vtflg,0        ; emulating a terminal?
  153.     je    tel1            ; e = no
  154.     or    al,emheath        ; say emulating some kind of terminal
  155. tel1:    mov    bx,portval
  156.     cmp    [bx].ecoflg,0        ; echoing?
  157.     jz    tel2
  158.     or    al,lclecho
  159. tel2:    call    getbaud            ; pickup current baud rate for port
  160.     mov    targ.flgs,al        ; store flags
  161.     mov    ah,flags.comflg        ; COMs port identifier
  162.     mov    targ.prt,ah        ; Port 1 or 2, etc
  163.     mov    ah,[bx].parflg        ; parity flag
  164.     mov    targ.parity,ah
  165.     mov    ax,[bx].baud        ; baud rate identifier
  166.     mov    targ.baudb,al
  167.     xor    ah,ah
  168.     test    flags.capflg,logses    ; select session logging flag bit
  169.     jz    tel3            ; z = no logging
  170.     mov    ah,capt            ; set capture flag
  171. tel3:    or    targ.flgs,ah
  172.  
  173. TEM:    call    serini            ; init serial port
  174.     jnc    tem1            ; nc = success
  175.     mov    ttyact,0        ; say we are no longer active
  176.     clc
  177.     ret                ; and exit Connect mode
  178.  
  179. tem1:    mov    dx,offset crlf        ; give user an indication that we are
  180.     mov    ah,prstr        ; entering terminal mode
  181.     int    dos
  182.     mov    ax,offset targ        ; Point to terminal arguments
  183.     call    term            ; Call the main Terminal procedure
  184.     mov    al,kbdflg        ; get the char from Term, if any
  185.     mov    kbdflg,0        ; clear    the flag
  186.     cmp    al,0            ; was there a char from Term?
  187.     jne    intch2            ; ne = yes, else ask for one from kbd
  188.  
  189. intchar:call    iseof            ; stdin at eof?
  190.     jnc    intch1            ; nc = not eof, get more
  191.     mov    al,'C'            ; use C when file is empty
  192.     jmp    intchc            ;  to provide an exit
  193. intch1:    mov    ah,coninq        ; read keyboard, no echo
  194.     int    dos            ; get a char
  195.     cmp    al,0            ; scan code indicator?
  196.     jne    intch2            ; ne = no, ascii
  197.     mov    ah,coninq        ; read and discard scan code
  198.     int    dos
  199.     jmp    short intch1        ; try again
  200. intch2:    cmp    al,' '            ; space?
  201.     je    tem            ; e = yes, ignore it
  202.     cmp    al,cr            ; check ^M (cr) against plain ascii M
  203.     je    tem            ; exit on cr
  204.     cmp    al,trans.escchr        ; Is it the escape char?
  205.     jne    intch3            ; ne = no
  206.     mov    ah,al
  207.     call    outchr
  208.     jmp    tem            ; Return, we are done here
  209. intch3:    push    es
  210.     push    ds
  211.     pop    es
  212.     mov    di,offset intclet    ; command letters
  213.     mov    cx,numlet        ; quantity of them
  214.     cmp    al,' '            ; control code?
  215.     jae    intch3a            ; ae = no
  216.     or    al,40H            ; convert control chars to printable
  217. intch3a:cmp    al,96            ; lower case?
  218.     jb    intch3b            ; b = no
  219.     and    al,not (20h)        ; move to upper case
  220. intch3b:cld
  221.     repne    scasb            ; find the matching letter
  222.     pop    es
  223.     jne    intch4            ; ne = not found, beep and get another
  224.     dec    di            ; back up to letter
  225.     sub    di,offset intclet    ; get letter number
  226.     shl    di,1            ; make it a word index
  227.     jmp    intcjmp[di]        ; dispatch to it
  228. intch4:    call    beep            ; say illegal character
  229.     jmp    intchar
  230.  
  231. intchb:    call    sendbr            ; 'B' send a break
  232.     jmp    tem            ; And return
  233.  
  234. intchc:    mov    ttyact,0        ; 'C' say we are no longer active
  235.     clc                ; and exit Connect mode
  236.     ret
  237.  
  238. intchf:    call    dumpscr            ; 'F' dump screen, use msy routine
  239.     jmp    tem            ; and return
  240.  
  241. intchh:    call    serhng            ; 'H' hangup phone
  242.     call    serrst            ; turn off port
  243.     jmp    tem
  244.  
  245. intchl:    call    sendbl            ; 'L' send a long break
  246.     jmp    tem
  247.  
  248. intchm:    cmp    flags.modflg,1        ; 'M' toggle mode line, enabled?
  249.     jne    intchma            ; ne = no, leave it alone
  250.     xor    targ.flgs,modoff    ; enabled, toggle its state
  251. intchma:jmp    tem            ; and reconnect
  252.  
  253. intchp:    call    fpush            ; 'P' push to DOS
  254.     mov    dx,offset sttmsg    ; say we have returned
  255.     mov    ah,prstr
  256.     int    dos
  257.     jmp    intchsb            ; wait for a space
  258.  
  259. intchq:    test    targ.flgs,capt        ; 'Q' suspend logging. Logging active?
  260.     jz    intchq1            ; z = no
  261.     and    targ.flgs,not capt    ; stop capturing
  262. intchq1:jmp    tem            ; and resume
  263.  
  264. intchr:    test    flags.capflg,logses    ; 'R' resume logging. Can we capture?
  265.     jz    intchr1            ; z = no
  266.     test    targ.flgs,capt        ; already capturing?
  267.     jnz    intchr1            ; yes, can't toggle back on then
  268.     or    targ.flgs,capt        ; else turn flag on
  269. intchr1:jmp    tem            ; and resume
  270.  
  271. intchs:    call    stat0            ; 'S' status, call stat0
  272.     mov    dx,offset sttmsg
  273.     mov    ah,prstr
  274.     int    dos
  275. intchsa:call    iseof            ; is stdin at eof?
  276.     jnc    intchsb            ; nc = not eof, get more
  277.     jmp    tem            ; resume if EOF
  278. intchsb:mov    ah,coninq        ; console input, no echo
  279.     int    dos
  280.     cmp    al,' '            ; space?
  281.     jne    intchsa
  282.     jmp    tem
  283.  
  284. intchu:    mov    ax,offset inthlp    ; '?' get help message
  285.     call    puthlp            ; write help msg
  286.     mov    dx,offset intprm
  287.     mov    ah,prstr        ; Print it
  288.     int    dos
  289.     jmp    intchar            ; Get another char
  290.  
  291. intchn:    mov    ah,0            ; '0' send a null
  292.     call    outchr
  293.     jmp    tem
  294. TELNET  ENDP
  295.  
  296. ; Reassure user    about connection to the host. Tell him what escape sequence
  297. ; to use to return and the communications port and baud; rate being used
  298.  
  299. DOMSG    PROC    NEAR
  300.     mov    ah,prstr
  301.     mov    dx,offset tmsg1
  302.     int    dos
  303.     call    escprt
  304.     mov    ah,prstr
  305.     mov    dx,offset tmsg3
  306.     int    dos
  307.     ret
  308. DOMSG    ENDP
  309.  
  310. ; print    the escape character in readable format.  
  311.  
  312. ESCPRT    PROC    NEAR
  313.     mov    dl,trans.escchr
  314.     cmp    dl,' '
  315.     jge    escpr2
  316.     push    dx
  317.     mov    ah,prstr
  318.     mov    dx,offset esctl
  319.     int    dos
  320.     pop    dx
  321.     add    dl,040H        ; Make it printable
  322. escpr2:    mov    ah,conout
  323.     int    dos
  324.     ret
  325. ESCPRT    ENDP
  326.  
  327.  
  328. ; Set parity for character in Register AL
  329.  
  330. dopar:    push    bx
  331.     mov    bx,portval
  332.     mov    bl,[bx].parflg        ; get parity flag byte
  333.     cmp    bl,parnon        ; No parity?
  334.     je    parret            ; Just return
  335.     and    al,07FH            ; Strip parity. Same as Space parity
  336.     cmp    bl,parspc        ; Space parity?
  337.     je    parret            ; e = yes, then we are done here
  338.     cmp    bl,parevn        ; Even parity?
  339.     jne    dopar0            ; ne = no
  340.     or    al,al
  341.     jpe    parret            ; pe = even parity now
  342.     xor    al,080H            ; Make it even parity
  343.     jmp    short parret
  344. dopar0:    cmp    bl,parmrk        ; Mark parity?
  345.     jne    dopar1            ; ne = no
  346.     or    al,080H            ; Turn on the parity bit
  347.     jmp    short parret
  348. dopar1:    cmp    bl,parodd        ; Odd parity?    
  349.     or    al,al
  350.     jpo    parret            ; Already odd, leave it
  351.     xor    al,080H            ; Make it odd parity
  352. parret:    pop    bx
  353.     ret
  354.  
  355. ; REPLAY filespec  through terminal emulator
  356. replay    proc    near
  357.     mov    dx,offset rdbuf        ; place for filename
  358.     mov    bx,offset rephlp    ; help
  359.     mov    repflg,0        ; clear the replay active flag
  360.     mov    ah,cmword        ; get filename
  361.     call    comnd
  362.     jc    replay2            ; c = failure
  363.     mov    ah,cmeol        ; get an EOL confirm
  364.     call    comnd
  365.     jc    replay2            ; c = failure
  366.     mov    ah,open2        ; open file
  367.     xor    al,al            ; open readonly
  368.     cmp    dosnum,200h        ; above DOS 2?
  369.     jna    replay1            ; na = no, so no shared access
  370.     mov    al,0+40h        ; open readonly, deny none
  371. replay1:mov    dx,offset rdbuf        ; asciiz filename
  372.     int    dos
  373.     jnc    replay3            ; nc = success
  374.     mov    ah,prstr
  375.     mov    dx,offset reperr    ; Cannot open that file
  376.     int    dos
  377.     clc
  378. replay2:ret
  379. replay3:mov    diskio.handle,ax    ; file handle
  380.     mov    repflg,1        ; set replay flag
  381.     call    telnet            ; enter Connect mode
  382.     mov    bx,diskio.handle
  383.     mov    ah,close2        ; close the file
  384.     int    dos
  385.     mov    repflg,0        ; clear the flag
  386.     clc
  387.     ret
  388. replay    endp
  389.  
  390. cptchr    proc    near            ; session capture routine, char in al
  391.     push    di
  392.     mov    di,capbp        ; buffer pointer
  393.     mov    byte ptr [di],al
  394.     inc    capbp
  395.     pop    di
  396.     dec    caplft            ; decrement chars remaining
  397.     jg    cptch1            ; more room, forget this part
  398.     call    cptdmp            ; dump the info
  399. cptch1:    ret
  400. cptchr    endp
  401.  
  402. cptdmp    proc    near            ; empty the capture buffer
  403.     push    ax
  404.     push    bx
  405.     push    cx
  406.     push    dx
  407.     mov    bx,sloghnd        ; get file handle
  408.     cmp    bx,0            ; is file open?
  409.     jle    cptdm1            ; le = no, skip it
  410.     mov    cx,cptsiz        ; original buffer size
  411.     sub    cx,caplft        ; minus number remaining
  412.     jl    cptdm2            ; means error
  413.     jcxz    cptdm1            ; z = nothing to do
  414.     mov    dx,offset capbuf    ; the capture routine buffer
  415.     mov    ah,write2        ; write with filehandle
  416.     int    dos            ; write out the block
  417.     jc    cptdm2            ; carry set means error
  418.     mov    capbp,offset capbuf
  419.     mov    caplft,cptsiz        ; init buffer ptr & chrs left
  420.     jmp    short cptdm1
  421. cptdm2:    and    flags.capflg,not logses    ; so please stop capturing
  422.     and    targ.flgs,not capt    ; so please stop capturing
  423.     mov    dx,offset erms23    ; tell user the bad news
  424.     mov    ah,prstr
  425.     int    dos
  426. cptdm1:    pop    dx
  427.     pop    cx
  428.     pop    bx
  429.     pop    ax
  430.     ret
  431. cptdmp    endp
  432.  
  433. pktcpt    proc    near            ; packet log routine, char in al
  434.     push    di
  435.     mov    di,pktbp        ; buffer pointer
  436.     mov    [di],al            ; store char in buffer
  437.     inc    pktbp            ; move pointer to next free byte
  438.     pop    di
  439.     dec    pktlft            ; decrement chars remaining
  440.     jg    pktcp1            ; g = more room, forget this part
  441.     call    pktdmp            ; dump the info
  442. pktcp1:    ret
  443. pktcpt    endp
  444.  
  445. pktdmp    proc    near            ; empty the capture buffer
  446.     push    ax
  447.     push    bx
  448.     push    cx
  449.     push    dx
  450.     mov    bx,ploghnd        ; get file handle
  451.     cmp    bx,0            ; is file open?
  452.     jle    cptdm1            ; le = no, skip it
  453.     mov    cx,cptsiz        ; original buffer size
  454.     sub    cx,pktlft        ; minus number remaining
  455.     jl    pktdm2            ; l means error
  456.     jcxz    pktdm1            ; z = nothing to do
  457.     mov    dx,offset pktbuf    ; the capture routine buffer
  458.     mov    ah,write2        ; write with filehandle
  459.     int    dos            ; write out the block
  460.     jc    pktdm2            ; carry set means error
  461.     mov    pktbp,offset pktbuf
  462.     mov    pktlft,cptsiz        ; init buffer ptr & chrs left
  463.     jmp    short pktdm1
  464. pktdm2:    and    flags.capflg,not logpkt    ; so please stop capturing
  465.     mov    dx,offset erms24    ; tell user the bad news
  466.     mov    ah,prstr
  467.     int    dos
  468.     call    clscp4            ; close the packet log
  469. pktdm1:    pop    dx
  470.     pop    cx
  471.     pop    bx
  472.     pop    ax
  473.     ret
  474. pktdmp    endp
  475.  
  476. ; CLOSE command
  477.  
  478. clscpt    proc    near
  479.     mov    ah,cmkey
  480.     mov    dx,offset clotab    ; close table
  481.     mov    bx,offset clohlp    ; help
  482.     call    comnd
  483.            jc    clscp2            ; c = failure
  484.     mov    tmp,bl
  485.     mov    ah,cmeol
  486.     call    comnd
  487.            jc    clscp2            ; c = failure
  488.     mov    bl,tmp
  489.     test    flags.capflg,0FFH    ; are any kinds active?
  490.     jz    clscp1            ; z = no
  491.            cmp    bl,logpkt+logses+logtrn    ; close all?
  492.     je    clscpi            ; e = yes
  493.     cmp    bl,logpkt        ; just packet?
  494.     je    clscp4
  495.     cmp    bl,logses        ; just session?
  496.     je    clscp6
  497.     cmp    bl,logtrn        ; just session?
  498.     je    clscp8
  499. clscp1:    mov    dx,offset erms22    ; say none active
  500.     mov    ah,prstr
  501.     int    dos
  502.     clc
  503. clscp2:    ret
  504.                     ; CLSCPI called at Kermit exit
  505. CLSCPI:    call    clscp4            ; close packet log
  506.     call    clscp6            ; close session log
  507.     call    clscp8            ; close transaction log
  508.     clc                ; return success
  509.     ret
  510.  
  511. clscp4:    push    bx            ; PACKET LOG
  512.     mov    bx,ploghnd        ; packet log handle
  513.     cmp    bx,0            ; is it open?
  514.     jle    clscp5            ; e = no
  515.     call    pktdmp            ; dump buffer
  516.     mov    ah,close2
  517.     int    dos
  518.     mov    ah,prstr
  519.     mov    dx,offset clpktlog    ; tell what we are doing
  520.     int    dos
  521. clscp5:    mov    ploghnd,-1        ; say handle is invalid
  522.     pop    bx
  523.     and    flags.capflg,not logpkt    ; say this log is closed
  524.     ret
  525.  
  526. clscp6:    push    bx            ; SESSION LOG
  527.     mov    bx,sloghnd        ; session log handle
  528.     cmp    bx,0            ; is it open?
  529.     jle    clscp7            ; e = no
  530.     call    cptdmp            ; dump buffer
  531.     mov    ah,close2
  532.     int    dos
  533.     mov    ah,prstr
  534.     mov    dx,offset clseslog    ; tell what we are doing
  535.     int    dos
  536. clscp7:    mov    sloghnd,-1        ; say handle is invalid
  537.     pop    bx
  538.     and    flags.capflg,not logses    ; say this log is closed
  539.     ret
  540.  
  541. clscp8:    push    bx            ; TRANSACTION LOG
  542.     mov    bx,tloghnd        ; transaction log handle
  543.     cmp    bx,0            ; is it open?
  544.     jle    clscp9            ; e = no
  545.     mov    ah,close2
  546.     int    dos
  547.     mov    ah,prstr
  548.     mov    dx,offset cltrnlog    ; tell what we are doing
  549.     int    dos
  550. clscp9:    mov    tloghnd,-1        ; say handle is invalid
  551.     pop    bx
  552.     and    flags.capflg,not logtrn    ; say this log is closed
  553.     ret
  554. clscpt    endp
  555.  
  556. ; worker: copy line from si to di, first removing trailing spaces, second
  557. ; parsing out curly braced strings, then third converting \{b##} in strings
  558. ; to binary numbers. Returns carry set if error; else carry clear, with byte
  559. ; count in cx. Braces are optional but must occur in pairs.
  560. ; Items which cannot be converted to legal numbers are copied verbatium
  561. ; to the output string (ex: \{c}  is copied as \{c}  but \{x0d} is hex 0dh).
  562. cnvlin    proc    near
  563.     push    ax
  564.     push    si            ; source ptr
  565.     push    di            ; destination ptr
  566.     push    es            ; end of save regs
  567.     push    ds            ; move ds into es
  568.     pop    es            ; use data segment for es:di
  569.     call    cnvstr            ; trim trailing, parse curly braces
  570.     xor    cx,cx            ; initialize returned byte count
  571. cnvln1:    cmp    byte ptr [si],0        ; at end of string?
  572.     je    cnvln2            ; e = yes, exit
  573.     call    katoi            ; read char, convert ascii to binary
  574.     cld
  575.     stosb                ; save the char
  576.     inc    cx            ; and count it
  577.     or    ah,ah            ; is returned number > 255?
  578.     jz    cnvln1            ; z = no, do more chars
  579.     push    ax
  580.     stosb                ; save high order byte next
  581.     pop    ax
  582.     inc    cx
  583.     jmp    short cnvln1        ; do more chars
  584. cnvln2:    mov    byte ptr [di],0        ; plant terminator
  585.     clc                ; clear c bit, success
  586.     pop    es            ; restore regs
  587.     pop    di            ; destination ptr
  588.     pop    si            ; source ptr
  589.     pop    ax
  590.     ret
  591. cnvlin    endp
  592.  
  593. ; Convert string by first remove trailing spaces and then removing surrounding
  594. ; curly brace delimiter pair. Converts text in place.
  595. ; Enter with source ptr in si.
  596. ; Preserves all registers, uses byte tmp. 9 Oct 1987 [jrd]
  597. cnvstr    proc    near
  598.     push    ax
  599.     push    cx
  600.     push    dx
  601.     push    si            ; save start of source string
  602.     push    di
  603.     push    es
  604.                     ; 1. Trim trailing spaces
  605.     mov    dx,si            ; source address
  606.     call    strlen            ; get current length to cx
  607.     jcxz    cnvst4            ; z = nothing there
  608.     mov    di,si            ; set di to source address
  609.     add    di,cx            ; start at end of string
  610.     dec    di            ; ignore terminator
  611.     mov    al,spc            ; scan while spaces
  612.     push    ds
  613.     pop    es            ; set es to data segment
  614.     std                ; search backward
  615.     repe    scasb            ; scan off trailing spaces
  616.     mov    byte ptr [di+2],0    ; terminate string after last text
  617.     cld
  618.     mov    di,si            ; set destination address to source
  619.                     ; 2. Parse off curly brace delimiters
  620.     cmp    byte ptr [si],braceop    ; opening brace?
  621.     jne    cnvst4            ; ne = no, ignore brace-matching code
  622.     inc    si            ; skip opening brace
  623.     mov    dl,braceop        ; opening brace (we count them up)
  624.     mov    dh,bracecl        ; closing brace (we count them down)
  625.     mov    tmp,1            ; we are at brace level 1
  626. cnvst1:    cld                ; search forward
  627.     lodsb                ; read a string char
  628.     stosb                ; store char (skips opening brace)
  629.     cmp    al,0            ; at end of string?
  630.     je    cnvst4            ; e = yes, we are done
  631.     cmp    al,dl            ; an opening brace?
  632.     jne    cnvst2            ; ne = no
  633.     inc    tmp            ; yes, increment brace level
  634.     jmp    short cnvst1        ;  and continue scanning
  635.  
  636. cnvst2:    cmp    al,dh            ; closing brace?
  637.     jne    cnvst1            ; ne = no, continue scanning
  638.     dec    tmp            ; yes, decrement brace level
  639.     cmp    byte ptr [si],0        ; have we just read the last char?
  640.     jne    cnvst3            ; no, continue scanning
  641.     mov    tmp,0            ; yes, this is the closing brace
  642. cnvst3:    cmp    tmp,0            ; at level 0?
  643.     jne    cnvst1            ; ne = no, #opening > #closing braces
  644.     mov    byte ptr [di-1],0    ; plant terminator on closing brace
  645.  
  646. cnvst4:    pop    es            ; recover original registers
  647.     pop    di
  648.     pop    si
  649.     pop    dx
  650.     pop    cx
  651.     pop    ax
  652.     ret
  653. cnvstr    endp
  654.  
  655. ; Convert ascii strings of the form "\{bnnn}" to a binary word in ax.
  656. ; The braces are optional but must occur in pairs. Numeric base indicator "b"
  657. ; is O or o or X or x or D or d or missing, for octal, hex, or decimal (def).
  658. ; Enter with si pointing at "\".
  659. ; Returns binary value in ax with carry clear and si to right of "}" or at
  660. ; terminating non-numeric char if successful; otherwise, a failure,
  661. ; return carry set with si = entry value + 1 and first read char in al.
  662.  
  663. katoi    proc    near
  664.     cld
  665.     lodsb                ; get first char
  666.     xor    ah,ah            ; clear high order field
  667.     push    cx            ; save working reg
  668.     push    si            ; save entry si+1
  669.     push    bx
  670.     push    ax            ; save read char
  671.     cmp    al,0            ; end of text?
  672.     je    katoi1a            ; e = yes, exit failure
  673.     cmp    al,'\'            ; escape char?
  674.     je    katoi1b            ; e = yes
  675. katoi1a:jmp    katoix            ; common jump point to exit failure
  676. katoi1b:lodsb                ; get next char, maybe brace
  677.     cmp    al,0            ; premature end?
  678.     je    katoi1a            ; e = yes, exit failure
  679.     xor    bx,bx            ; no conv yet, assume no opening brace
  680.     cmp    al,braceop        ; opening brace?
  681.     jne    katoi2            ; ne = no, have number or base
  682.     mov    bl,bracecl        ; remember a closing brace is needed
  683.     lodsb                ; get number base, if any
  684. katoi2:    xor    cx,cx            ; temporary place for binary value
  685.     mov    nbase,10        ; assume decimal numbers
  686.     cmp    al,0            ; premature end?
  687.     je    katoix            ; e = yes, exit failure
  688.     cmp    al,'a'            ; lower case?
  689.     jb    katoi3            ; b = no
  690.     cmp    al,'z'            ; in range of lower case?
  691.     ja    katoi3            ; a = no
  692.     and    al,5fh            ; map to upper case
  693. katoi3:    cmp    al,'O'            ; octal?
  694.     jne    katoi4            ; ne = no
  695.     mov    nbase,8            ; set number base
  696.     jmp    short katoi6
  697. katoi4:    cmp    al,'X'            ; hex?
  698.     jne    katoi5            ; ne = no
  699.     mov    nbase,16
  700.     jmp    short katoi6
  701. katoi5:    cmp    al,'D'            ; decimal?
  702.     jne    katoi7            ; ne = no base char, assume decimal
  703.     mov    nbase,10
  704. katoi6:    lodsb                ; get a digit
  705. katoi7:    cmp    al,0            ; premature end?
  706.     je    katoi8a            ; e = yes, use it as a normal end
  707.     cmp    al,bl            ; closing brace?
  708.     je    katoi9            ; e = yes
  709.     call    cnvdig            ; convert ascii to binary digit
  710.     jc    katoi8            ; c = cannot convert
  711.     inc    bh            ; say we did a successful conversion
  712.     xor    ah,ah            ; clear high order value
  713.     push    ax            ; save this byte's value
  714.     xchg    ax,cx            ; put binary summation in ax
  715.     mul    nbase            ; scale up current sum
  716.     xchg    ax,cx            ; put binary back in cx
  717.     pop    ax            ; recover binary digit
  718.     add    cx,ax            ; form running sum
  719.     jc    katoix            ; c = overflow error, exit
  720.     cmp    dx,0            ; overflow?
  721.     jne    katoix            ; ne = yes, exit with error
  722.     jmp    short katoi6        ; get more
  723.  
  724. katoi8:    cmp    bl,0            ; closing brace needed?
  725.     jne    katoix            ; ne = yes, but not found
  726. katoi8a:dec    si            ; backup to reread terminator
  727. katoi9:    cmp    bh,0            ; did we do any conversion?
  728.     je    katoix            ; e = no, exit failure
  729.     pop    ax            ; throw away old saved ax
  730.     pop    bx            ; restore bx
  731.     pop    ax            ; throw away starting si, keep current
  732.     mov    ax,cx            ; return final value in ax
  733.     pop    cx            ; restore old cx
  734.     clc                ; clear carry for success
  735.     ret
  736. katoix:    pop    ax            ; restore first read al
  737.     pop    bx
  738.     pop    si            ; restore start value + 1
  739.     pop    cx            ; restore old cx
  740.     stc                ; set carry for failure
  741.     ret
  742. katoi    endp
  743.  
  744. cnvdig    proc    near            ; convert ascii code in al to binary
  745.     push    cx            ; return carry set if cannot
  746.     push    es            ; nbase has numeric base
  747.     push    di
  748.     push    ax
  749.     cmp    al,'a'            ; lower case?
  750.     jb    cnvdig1            ; b = no
  751.     cmp    al,'f'            ; highest hex digit
  752.     ja    cnvdigx            ; a = illegal symbol
  753.     sub    al,'a'-'A'        ; convert 'a' to 'f' to upper case
  754. cnvdig1:mov    di,offset numset    ; set of legal number symbols
  755.     mov    cx,nbase        ; number of legal symbols in this base
  756.     cmp    cx,cx            ; preset z flag
  757.     push    ds
  758.     pop    es            ; point es at data segment
  759.     cld                ; scan forward
  760.     repne    scasb            ; find character in set
  761.     jne    cnvdigx            ; ne = not found
  762.     inc    cx            ; offset auto-dec of repne scasb above
  763.     sub    cx,nbase        ; counted off minus length
  764.     neg    cx            ; two's complement = final value
  765.     pop    ax            ; saved ax
  766.     mov    ax,cx            ; return binary in al
  767.     clc                ; c clear for success
  768.     jmp    short cnvdixx        ; exit
  769. cnvdigx:stc                ; c set for failure
  770.     pop    ax
  771. cnvdixx:pop    di
  772.     pop    es
  773.     pop    cx
  774.     ret
  775. cnvdig    endp    
  776.  
  777. decout    proc    near        ; display decimal number in ax
  778.     push    ax
  779.     push    cx
  780.     push    dx
  781.     mov    cx,10        ; set the numeric base
  782.     call    valout        ; convert and output value
  783.     pop    dx
  784.     pop    cx
  785.     pop    ax
  786.     ret
  787. decout    endp
  788.  
  789. valout    proc    near        ; output number in ax using base in cx
  790.                 ; corrupts ax and dx
  791.     xor    dx,dx        ; clear high word of numerator
  792.     div    cx        ; (ax / cx), remainder = dx, quotient = ax
  793.     push    dx        ; save remainder for outputting later
  794.     or    ax,ax        ; any quotient left?
  795.     jz    valout1        ; z = no
  796.     call    valout        ; yes, recurse
  797. valout1:pop    dx        ; get remainder
  798.     add    dl,'0'        ; make digit printable
  799.     cmp    dl,'9'        ; above 9?
  800.     jbe    valout2        ; be = no
  801.     add    dl,'A'-1-'9'    ; use 'A'--'F' for values above 9
  802. valout2:mov    ah,conout
  803.     int    dos
  804.     ret
  805. valout    endp
  806.  
  807. ; Convert input in buffer pointed to by SI to real number which is returned
  808. ; in AX.  Enter with string size in AH.
  809. ; Return carry set on failure, carry clear on success.
  810. ATOI    PROC    NEAR
  811.     mov    bx,0        ; high order of this stays 0
  812.     mov    tmp,0        ; No input yet
  813.     mov    cl,ah        ; Number of chars of input
  814.     mov    ch,0        ; size of string
  815.     mov    ax,0        ; init sum
  816.     cld
  817. atoi0:    jcxz    atoi4        ; Fail on no input
  818.     lodsb            ; get an input char
  819.     dec    cx        ; count number remaining
  820.     cmp    al,' '        ; leading space?
  821.     je    atoi0        ; e = yes, skip it
  822.     cmp    al,','        ; comma separator?
  823.     je    atoi0        ; e = yes, skip it
  824.     dec    si        ; back up source pointer for reread below
  825.     inc    cx        ; and readjust byte counter
  826.     mov    ax,0        ; clear sum
  827. atoi1:    push    ax        ; save sum
  828.     lodsb            ; read a byte into al
  829.     mov    bl,al        ; put it into bl
  830.     pop    ax        ; regain sum
  831.     cmp    bl,'9'        ; check range for '0' to '9'
  832.     ja    atoi2        ; above '9'
  833.     cmp    bl,'0'
  834.     jb    atoi2        ; below '0'
  835.     sub    bl,'0'        ; take away ascii bias
  836.     mul    ten        ; sum * 10. dx = high, ax = low
  837.     add    ax,bx        ; add current value
  838.     mov    tmp,1        ; say have sum being computed
  839.     loop    atoi1
  840.     inc    si        ; inc for dec below
  841. atoi2:    dec    si        ; point at terminator
  842.     cmp    tmp,0        ; were any digits discovered?
  843.     je    atoi4        ; e = no, fail
  844.     clc            ; success
  845.     ret
  846. atoi4:    mov    dx,offset erms25 ; Input must be numeric
  847.     stc            ; failure
  848.     ret
  849. ATOI    ENDP
  850.  
  851. ; Write binary number in AX as decimal asciiz to buffer pointer DI.
  852. dec2di    proc    near        ; output number in ax using base in cx
  853.                 ; corrupts ax, cx, and dx
  854.     mov    cx,10
  855. dec2di1:xor    dx,dx        ; clear high word of numerator
  856.     div    cx        ; (ax / cx), remainder = dx, quotient = ax
  857.     push    dx        ; save remainder for outputting later
  858.     or    ax,ax        ; any quotient left?
  859.     jz    dec2di2        ; z = no
  860.     call    dec2di1        ; yes, recurse
  861. dec2di2:pop    dx        ; get remainder
  862.     add    dl,'0'        ; make digit printable
  863.     mov    [di],dl        ; store char in buffer
  864.     inc    di
  865.     mov    byte ptr[di],0    ; add terminator
  866.     ret
  867. dec2di    endp
  868.  
  869. ; WRITE {log} {object} {optional text}
  870. Write    proc    near
  871.     mov    ah,cmkey        ; get kind of log file
  872.     mov    dx,offset writetab    ; table of possibilities
  873.     xor    bx,bx            ; help, when we get there
  874.     call    comnd
  875.     jc    write1            ; c = failure
  876.     mov    tmp,bl            ; save log file kind
  877.     mov    ah,cmkey        ; get kind of object to write
  878.     mov    comand.cmkeep,1        ; keep Take/Macro open after this call
  879.     mov    dx,offset wrtobj    ; table of objects
  880.     xor    bx,bx
  881.     call    comnd
  882.     jc    write1            ; c = failure
  883.     jmp    bx            ; do the routine to do the writing
  884. write1:    ret
  885. write    endp                ; jmp rskp is success, ret is fail
  886.  
  887.  
  888. ; WRITE <log> ARGC
  889. wrtargc    proc    near
  890.     xor    ax,ax
  891.     mov    di,offset rdbuf        ; where to write the buffer
  892.     cmp    taklev,0        ; in a Take/Macro?
  893.     je    wrtarg1            ; e = no
  894.     mov    bx,takadr        ; current Take structure
  895.     mov    ax,[bx].takargc        ; get ARGC
  896. wrtarg1:call    dec2di            ; write as ascii
  897.     mov    word ptr [di],0020h    ; space and null terminator
  898.     inc    di
  899.     mov    temp,di            ; place for additional text
  900.     jmp    wrttxt1            ; add any trailing text
  901. wrtargc    endp
  902.  
  903. ; WRITE <log> COUNT
  904. wrtcnt    proc    near
  905.     xor    ax,ax
  906.     mov    di,offset rdbuf        ; where to write the buffer
  907.     cmp    taklev,0        ; in a Take/Macro?
  908.     je    wrtcnt1            ; e = no
  909.     mov    bx,takadr        ; current Take structure
  910.     mov    ax,[bx].takctr        ; get COUNT
  911. wrtcnt1:call    dec2di            ; write as ascii
  912.     mov    word ptr [di],0020h    ; space and null terminator
  913.     inc    di
  914.     mov    temp,di            ; place for additional text
  915.     jmp    wrttxt1            ; add any trailing text
  916. wrtcnt    endp
  917.  
  918. ; Write <log> DATE <optional text>
  919. wrtdate    proc    near
  920.     mov    ah,getdate        ; DOS date (cx= yyyy, dh= mm, dl= dd)
  921.     int    dos
  922.     mov    di,offset rdbuf
  923.     push    cx            ; save cx
  924.     push    dx            ; save dx
  925.     xor    ah,ah
  926.     mov    al,dh            ; Months
  927.     cmp    al,10            ; leading tens digit present?
  928.     jae    wrtdat1            ; ae = yes
  929.     mov    byte ptr [di],'0'    ; insert leading 0
  930.     inc    di
  931. wrtdat1:call    dec2di            ; write decimal asciiz to buffer
  932.     mov    byte ptr [di],'-'
  933.     inc    di
  934.     pop    dx            ; recover dx
  935.     xor    ah,ah
  936.     mov    al,dl            ; Days
  937.     cmp    al,10            ; leading digit?
  938.     jae    wrtdat2            ; ae = yes
  939.     mov    byte ptr [di],'0'    ; make our own
  940.     inc    di
  941. wrtdat2:call    dec2di            ; write decimal asciiz to buffer
  942.     mov    byte ptr [di],'-'
  943.     inc    di
  944.     pop    cx            ; recover cx
  945.     mov    ax,cx            ; Year (omit century)
  946.     call    dec2di            ; write decimal asciiz to buffer
  947.     mov    word ptr [di],0020h    ; space and null terminator
  948.     inc    di
  949.     mov    temp,di            ; place for additional text
  950.     jmp    wrttxt1            ; add any trailing text
  951. wrtdate    endp
  952.  
  953. ; WRITE <log> ERRORLEVEL
  954. wrterr    proc    near
  955.     mov    di,offset rdbuf        ; where to write the buffer
  956.     mov    al,errlev        ; current Errorlevel
  957.     xor    ah,ah
  958.     call    dec2di            ; write as ascii
  959.     mov    word ptr [di],0020h    ; space and null terminator
  960.     inc    di
  961.     mov    temp,di            ; place for additional text
  962.     jmp    wrttxt1            ; add any trailing text
  963. wrterr    endp
  964.  
  965. ; Write <log> INPUT-buffer (no trailing text)
  966. wrtinp    proc    near
  967.     mov    ah,cmeol        ; get a confirm
  968.     call    comnd
  969.     jnc    wrtin6            ; nc = success
  970.     ret                ; failure
  971. wrtin6:    push    es
  972.     call    buflog            ; get INPUT buffer pointers
  973.     mov    bx,cx            ; length of buffer (and max offset)
  974.     mov    di,offset rdbuf        ; where to write the buffer
  975.     mov    byte ptr [di],'<'    ; start with "<# unread chars>"
  976.     inc    di
  977.     push    cx
  978.     push    dx
  979.     call    dec2di            ; ax has unread count, bufcnt
  980.     pop    dx
  981.     pop    cx
  982.     mov    byte ptr [di],'>'
  983.     inc    di
  984. wrtin1:    mov    al,es:[si]        ; extract a buffer char into al
  985.     inc    si            ; move pointer to next byte
  986.     test    al,80h            ; high bit set?
  987.     jz    wrtin2            ; z = no
  988.     mov    byte ptr [di],'~'    ; yes, show a tilde
  989.     inc    di
  990. wrtin2:    and    al,7fh            ; strip eighth bit
  991.     cmp    al,' '            ; control code?
  992.     jae    wrtin3            ; ae = no
  993.     mov    byte ptr [di],'^'    ; yes, show caret
  994.     inc    di
  995.     or    al,40h            ; convert char to upper case letter
  996. wrtin3:    mov    [di],al
  997.     inc    di            ; where to write next byte
  998.     cmp    di,offset rdbuf+78    ; line full?
  999.     jb    wrtin4            ; b = no, have more room
  1000.     mov    word ptr [di],0a0dh    ; add cr/lf
  1001.     mov    byte ptr [di+2],0
  1002.     push    bx
  1003.     push    cx
  1004.     push    dx
  1005.     push    si
  1006.     push    es
  1007.     call    wrtcom            ; dump what we have
  1008.     pop    es
  1009.     pop    si
  1010.     pop    dx
  1011.     pop    cx
  1012.     pop    bx
  1013.     mov    di,offset rdbuf        ; reset to start of our local buffer
  1014. wrtin4:    cmp    si,bx            ; beyond end of Input buffer?
  1015.     jb    wrtin5            ; b = not yet
  1016.     xor    si,si            ; reset to start of INPUT-buf (wrap)
  1017. wrtin5:    loop    wrtin1
  1018.     mov    word ptr [di],0a0dh    ; add cr/lf
  1019.     mov    byte ptr [di+2],0
  1020.     pop    es
  1021.     jmp    wrtcom            ; write the last of INPUT buffer
  1022. wrtinp    endp
  1023.  
  1024. ; Write <log> PATH <optional text>
  1025. wrtpath    proc    near
  1026.     mov    si,offset rdbuf        ; work buffer
  1027.     mov    ah,gcurdsk        ; get current disk
  1028.     int    dos
  1029.     add    al,'A'            ; make al = 0 == 'A'
  1030.     mov    [si],al
  1031.     mov    word ptr [si+1],'\:'
  1032.     add    si,3            ; end with a colon and backslash
  1033.     mov    ah,gcd            ; get current directory (path really)
  1034.     xor    dl,dl            ; use current drive
  1035.     int    dos            ; get ds:si = asciiz path (no drive)
  1036.     mov    dx,si
  1037.     call    strlen
  1038.     add    si,cx
  1039.     mov    word ptr [si],0020h    ; space and null terminator
  1040.     inc    di
  1041.     mov    temp,di            ; place for additional text
  1042.     jmp    wrttxt1            ; add any trailing text
  1043. wrtpath    endp
  1044.  
  1045. ; Write <log> TIME <optional text>
  1046. wrttime    proc    near
  1047.     mov    ah,gettim        ; DOS tod (ch=hh, cl=mm, dh=ss, dl=.s)
  1048.     int    dos
  1049.     mov    di,offset rdbuf
  1050.     push    dx            ; save dx
  1051.     xor    ah,ah
  1052.     mov    al,ch            ; Hours
  1053.     cmp    al,10            ; leading digit?
  1054.     jae    wrttim1            ; ae = yes
  1055.     mov    byte ptr [di],'0'    ; make our own
  1056.     inc    di
  1057. wrttim1:push    cx
  1058.     call    dec2di            ; write decimal asciiz to buffer
  1059.     pop    cx
  1060.     mov    byte ptr [di],':'
  1061.     inc    di
  1062.     xor    ah,ah
  1063.     mov    al,cl            ; Minutes
  1064.     cmp    al,10            ; leading digit?
  1065.     jae    wrttim2            ; ae = yes
  1066.     mov    byte ptr [di],'0'    ; make our own
  1067.     inc    di
  1068. wrttim2:call    dec2di            ; write decimal asciiz to buffer
  1069.     mov    byte ptr [di],':'
  1070.     inc    di
  1071.     pop    dx
  1072.     push    dx
  1073.     xor    ah,ah
  1074.     mov    al,dh            ; Seconds
  1075.     cmp    al,10            ; leading digit?
  1076.     jae    wrttim3            ; ae = yes
  1077.     mov    byte ptr [di],'0'    ; make our own
  1078.     inc    di
  1079. wrttim3:call    dec2di            ; write decimal asciiz to buffer
  1080.     mov    byte ptr [di],'.'
  1081.     inc    di
  1082.     pop    dx
  1083.     xor    ah,ah
  1084.     mov    al,dl            ; Hundredths of seconds
  1085.     cmp    al,10            ; leading digit?
  1086.     jae    wrttim4            ; ae = yes
  1087.     mov    byte ptr [di],'0'    ; make our own
  1088.     inc    di
  1089. wrttim4:call    dec2di            ; write decimal asciiz to buffer
  1090.     mov    word ptr [di],0020h    ; space and null terminator
  1091.     inc    di
  1092.     mov    temp,di            ; place for additional text
  1093.     jmp    wrttxt1            ; add any trailing text
  1094. wrttime    endp
  1095.  
  1096. ; Write <log> Version (no optional text)
  1097. wrtver    proc    near
  1098.     mov    si,offset verident    ; MS Kermit version string in mssker
  1099.     mov    di,offset rdbuf
  1100.     cld
  1101. wrtver1:lodsb
  1102.     mov    [di],al
  1103.     inc    di
  1104.     cmp    al,'$'            ; end of string?
  1105.     jne    wrtver1            ; ne = no, continue copying
  1106.     dec    di
  1107.     mov    word ptr [di],0020h    ; space and null terminator
  1108.     inc    di
  1109.     mov    temp,di            ; place for additional text
  1110.     jmp    wrttxt1            ; add any trailing text
  1111. wrtver    endp
  1112.  
  1113. ; Write <log> TEXT <optional text>
  1114. wrttxt    proc    near            ; write string of text
  1115.     mov    comand.cmcr,1        ; bare cr's allowed without error
  1116.     mov    temp,offset rdbuf    ; our buffer
  1117. wrttxt1:mov    ah,cmline        ; get string to be written
  1118.     mov    bx,temp            ; where to put text
  1119.     mov    dx,offset rdbuf + 255   ; length rdbuf, end of buffer
  1120.     sub    dx,bx            ; minus used part of buffer, yields
  1121.     cmp    dx,127            ;  length remaining in buffer
  1122.     jbe    wrttxt2            ; be = regular buffer length
  1123.     mov    dl,127            ; cut back to that size
  1124. wrttxt2:mov    comand.cmblen,dl    ;  length remaining in buffer
  1125.     mov    dx,offset msgtxt    ; help
  1126.     call    comnd
  1127.     mov    si,temp            ; start of text in buffer
  1128.     mov    di,si            ; convert in-place, to asciiz
  1129.     call    cnvlin
  1130.     jmp    wrtcom            ; finish in common write code
  1131. wrttxt    endp
  1132.  
  1133. ; Writes contents of buffer rdbuf (asciiz) to log file kind held in tmp
  1134. ; and returns to command parser
  1135. wrtcom    proc    near            ; common write code
  1136.     mov    ah,cmeol
  1137.     call    comnd
  1138.     jnc    wpkt0
  1139.     ret                ; c = failure
  1140. wpkt0:    mov    bl,tmp            ; log file kind
  1141.     cmp    bl,logpkt        ; Packet log?
  1142.     jne    wses1            ; ne = no
  1143.     mov    si,offset rdbuf
  1144.     mov    dx,si
  1145.     call    strlen
  1146.     jcxz    wpkt2            ; z = no chars to write
  1147. wpkt1:    lodsb                ; get byte to al
  1148.     call    pktcpt            ; write to packet log
  1149.     loop    wpkt1
  1150. wpkt2:    clc                ; say success
  1151.     ret
  1152.  
  1153. wses1:    cmp    bl,logses        ; Session log?
  1154.     jne    wtrn1            ; ne = no
  1155.     mov    si,offset rdbuf
  1156.     mov    dx,si
  1157.     call    strlen
  1158.     jcxz    wses3            ; z = no chars to write
  1159. wses2:    lodsb                ; get byte to al
  1160.     call    cptchr            ; write to log
  1161.     loop    wses2            ; do cx chars
  1162. wses3:    clc                ; say success
  1163.     ret
  1164.  
  1165. wtrn1:    cmp    bl,logtrn        ; Transaction log?
  1166.     jne    wtscn            ; ne = no
  1167.     mov    bx,tloghnd        ; file open?
  1168.     cmp    bx,0
  1169.     jle    wtrn2            ; le = no, forget it
  1170.     mov    dx,offset rdbuf
  1171.     call    strlen            ; length to cx
  1172.     jcxz    wtrn2            ; z = nothing to write
  1173.     mov    ah,write2        ; write to file handle in bx
  1174.     int    dos
  1175. wtrn2:    clc                ; success
  1176.     ret
  1177. wtscn:    cmp    bl,80h            ; write screen?
  1178.     jne    wtscn1            ; ne = no
  1179.     mov    dx,offset rdbuf
  1180.     call    strlen            ; length to cx
  1181.     jcxz    wtrn2            ; z = nothing to write
  1182.     xor    bx,bx            ; handle is stdout
  1183.     mov    ah,write2        ; write to file handle in bx
  1184.     int    dos
  1185. wtscn1:    clc
  1186.     ret
  1187. wrtcom    endp
  1188.  
  1189. code    ends 
  1190.     end
  1191.