; * * * * * * * * * * * * * * * version 2.7 * * * * * * * * * * * * * * * * ; [fdc] Print message about how to get help during connect. ; [29e] Move terminal session logging to terminal module. ; * * * * * * * * * * * * * * * version 2.6 * * * * * * * * * * * * * * * * ; [24b revisited] Fix handling of double-escape character ; RonB, 03/22/84 ; [26] ; Move TELNET stuff from KERMIT to a this module: KERTRM. ; This is to modularize terminal emulation. ; ; integrate keyboard check in-line. This allows keyboard check ; between port checks to work without blowing the stack. ; ; to improve speed, let the port-to-screen routine loop for a certain ; number of characters before checking the keyboard. If we ; check every time, we lose a few characters at 9600 baud ; without flow control. ; ; Mar-1984. R. Garland - Columbia University. ; ; [24] ; (a) Add terminal session logging (KERMIT,KERSYS,KERUTL) ; (b) Allow escape character to local-echo (KERMIT) ; RonB, 03/15/84 ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * cseg $ ;resume code segment ; This is the CONNECT command. It makes the local Kermit act as a terminal. telnet: mov ah,cmcfm call comnd ;Get a confirm. jmp r ; Didn't get a confirm. mov dx, offset inms01 ;Confirmed, print informatory message. call tcrmsg call escprt mov dx, offset inms02 call tmsg ;[fdc] Say how to get help during connect. call escprt ;[fdc] mov dx, offset inms25 ;[fdc] call tmsgcr ;[fdc] cmp logflg, 0 ;Is logging specified? ;[24a] begin je telnt1 call logopn ;If so, open the log file jmp logerr ;[24a] end telnt1: ;Check keyboard. mov teloop, cx ;initialize loop counter call dbinst ;Any chars out there? jmp telntx ; If not, check serial port call dbin ;Yes, then get the char. cmp al, escchr ;Is it an escape char? jz intchr ;If so go process it. telnty: call dopar ;Set parity (if any). ;[24b] mov dx, ax call prtout ;Output the char to the port. cmp ecoflg, 0 ;Is the echo flag turned on? jz telnt2 ;no - go on and dl, 7FH ;Turn off the parity bit. call dbout ;Echo the character. telntx: mov cx, telnct ;load count for telnt2 loop telnt2: ;Check serial port. mov teloop, cx ;save loop count call instat ;Any characters available? jmp telnt1 ; No, check keyboard call inchr ;Get the character. and al, 7FH ;Strip off parity bit. mov dl, al ;Get the character. call dbout ;output to screen. mov cx, teloop ;get loop counter loop telnt2 ;loop a bunch of characters before ;checking keyboard - for speed. jmp telnt1 ;go back and check keyboard. intchr: call dbin ;Get a char. cmp al, 0 ;Is the char a null? jz intchr ;If so, go until we get a char. mov bl, al ;Save the actual char. and al, 137O ;Convert to upper case. ;C = close cmp al, 'C' ;Is it close? jne intch0 call logcls ;Close the log file ;[24a] mov dx, offset inms03 call tcmsgc ;return to micro message jmp rskp ;return from telnet ;B = break intch0: cmp al,'B' ;[19e] Is it "send break"? jne intch1 ;[19e] no. call prtbrk ;[19e] send a break. jmp telnt2 ;[19e] ;escape character intch1: cmp bl, escchr ;Is it the escape char? jne intch2 ;If not, go send a beep to the user. mov al, bl ;If so, uncapitalize it ;[24b] jmp telnty ;go on, we are done here. ;[24b] ;? = help intch2: cmp bl, '?' ;Is it a cry for help? ;[20c] jne intch3 mov dx, offset inthlp ;If so, display help message on screen call tcrmsg call escprt mov dx, offset inthl2 call tmsg call escprt mov dx, offset inthl3 call tmsgcr jmp intchr ;Keep looking for escape character. ;[20c] ;L = toggle logging intch3: cmp al, 'L' ;Is it the logging toggle? ;[24a] begin jne intch4 cmp logflg, 0 ;Is logging now off? jne intc32 intc31: mov logflg, 0FFh ;If so, set to 'on' value. call logopn ;Open log file. jmp logerr jmp telnt2 intc32: mov logflg, 0 call logcls ;Close the log file. jmp telnt2 ;[24a] end ;Q = quit logging ;[29e] begin intch4: cmp al, 'Q' jne intch5 cmp logflg, 0 ;If logging currently enabled, jne intc32 ; go set flag to 'off' jmp telnt2 ;R = resume logging intch5: cmp al, 'R' jne intch6 cmp logflg, 0 ;If logging currently disabled, je intc31 ; go set flag to 'on' jmp telnt2 ;[29e] end ;error = beep! intch6: mov dl, bell ;Otherwise send a beep. call dbout jmp telnt2 logerr: mov logflg, 0 ;Reset logging on file error ;[24a] begin call logcls ;Make sure log file is closed mov dx, offset erms22 ;Print an error message. call tcrmsg mov dx, offset lfcb call tfile call tcrlf jmp rskp ;And keep doing whatever we were ;[24a] end ; These are the file handling routines for terminal session logging. ; LOGOPN opens the logfile in lfcb. logopn: mov byte ptr lfcb+12,0 mov byte ptr lfcb+13,0 mov byte ptr lfcb+14,0 mov dx, offset lfcb call gtjfn ;Is file already present? cmp al, 0FFh jne logo4 ;If so, go seek to its end & open it. mov bx, offset lfcb+1 ;Don't allow wild or blank name cmp byte ptr [bx], ' ' je logo2 cmp wldflg, 0 je logo3 logo2: cld push ds pop es mov di, offset lfcb ;Make it "KERMIT.LOG" instead mov si, offset lognam mov cx, 12 rep movsb logo3: mov dx, offset lfcb call create ;Otherwise create the file. mov bx, offset lfcb mov byte ptr 32[bx], 0 ;Zero "CR" field mov bx, offset dma cmp al, 0FFh ;If no more directory space jne logo9 ret ; then return an error logo4: cld push ds pop es mov di, offset lfcb+1 ;Get the unambiguous filename mov si, offset dma+1 mov cl, 5 shl al, cl mov ah, 0 add si, ax mov cx, 11 rep movsb mov dx, offset lfcb call openf mov dx, offset lfcb ;Get existing file size call sizef mov bx, offset lfcb cmp byte ptr 35[bx], 0 je logo5 ;If file is too full ret ; then return an error logo5: cmp word ptr 33[bx], 0 ;Is the file totally empty? je logo8 ; if so, don't look for control-Z. dec word ptr 33[bx] ;Point to last record in file mov dx, offset lfcb call rinr ;Read random mov bx, offset dma-1 ;Look for the terminating control-Z. mov cx, 80h logo6: inc bx cmp byte ptr [bx], 'Z'-100O je logo9 loop logo6 mov dx, offset lfcb call soutr ;If no control-Z, then start a new buffer logo8: mov bx, offset dma logo9: mov bufpnt, bx ;Save current buffer location. mov logfil, 0FFh ;Flag that file is open mov dx, offset infm11 ;And display status on the terminal call tmsg mov dx, offset lfcb ;Including the file name call tfile mov dx, offset infm12 call tmsgcr jmp rskp ;Return success. ; LOGCLS - closes the log file, but only if it was open logcls: cmp logfil, 0 ;Is file open? je logc3 ;No, just return. cmp bufpnt, offset dma ;Do we have an empty buffer? je logc2 mov bx, bufpnt ;If not, fill remainder with control-Z's mov cx, offset DMA+80h sub cx, bx mov al, 'Z'-100O logc1: mov [bx], al inc bx loop logc1 mov dx, offset lfcb ;Write out last buffer call soutr logc2: mov dx, offset lfcb ;Close the log file call closf mov dx, offset infm13 ;Tell user so. call tcmsgc mov logfil, 0 ;Show file closed. logc3: ret ;[24a] end ; data specific to terminal emulation dseg $ telnct dw 10 ;count of characters to take from port ;for the screen before checking keyboard. teloop dw 0 ;active loop counter logflg db deflog ;Is logging enabled? ;[24a] begin logfil db 0 ;Is the log file open? lognam db 0,'KERMIT LOG' ;Default log filename lfcb db 0,'KERMIT LOG' ;Logging file control block rb 24 ;[24a] end