home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
KERMIT
/
CP411SRC.ARK
/
cpstt.asm
< prev
next >
Wrap
Assembly Source File
|
1991-04-23
|
30KB
|
863 lines
; CPSTT.ASM
; KERMIT - (Celtic for "FREE")
;
; This is the CP/M-80 implementation of the Columbia University
; KERMIT file transfer protocol.
;
; Version 4.0
;
; Copyright June 1981,1982,1983,1984,1985
; Columbia University
;
; Originally written by Bill Catchings of the Columbia University Center for
; Computing Activities, 612 W. 115th St., New York, NY 10025.
;
; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
; others.
;
; This file contains the code for the TRANSMIT and CONNECT commands,
; which communicate with a host which is not running KERMIT.
;
; revision history:
;
;edit 12, 31-Jan-1991 by MF. Delete call to "inbuf" after "xmit1" in
; the TRANSMIT command. "getfil" initializes various counters so that
; when "in1chr" is first called, "inbuf" will be called immediately
; and will read sectors of the file to be transmitted from disk.
; This, along with a fix to "in1chr" in CPSUTL.ASM, fixes a bug
; discovered by Lance Tagliapietra of the University of Wisconsin at
; Platteville wherein the TRANSMIT command was failing to transmit some
; characters in files over one sector in length. See CPSUTL.ASM,
; edit 29.
; edit 11, 10 September, a987, by OBSchou. Modified TRANSMIT command
; to TRANSMIT <file> <string>
;
; edit 10, 27 August, 1987 by OBSchou. Fixed bugs in Transmit, but I may
; be introducing problems for IBM/CMS or half duplex systems. What
; does this combination do??
;
; edit 9 30 March, 1987 by OBSchou to replace the TRANSMIT routine.
; Syntax is now TRANSMIT file after a previous
; INPUT <wait time> <string to wait for>
;
; edit 8 19 June, 1986 by OBSchou. Modified the interupt testing routine
; to see if the command was a 'D' (Drop the line), in which case also
; do a 'C', ie disconnect. This is really a little too much of a
; system dependent thing.
; For now, Ill leave it here, and possibly move it later.
;
; edit 7 30 May 1986 OBSchou. Moved xon/xoff control (ie XON/OFF sent to host)
; out to CPSUTL so that ther printer routine can use it too.
;
; edit 6 30 April, 1986 by OBSchou.
; Fixed transmit bug, so as soon as the protocol character is
; received from the host is received then another line is sent.
; added in a comchr (ds 1) to save the character read from the comm
; line in prtchr, and is restored in a on return.
;
; edit 5 7 March, 1986 by OBSchou Loughborough University.
; Need to save the E register before calling outmdm (in CPSSYS.ASM)
; if doing Half duplex. Push/pop DE should sort this problem
;
; edit 4: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809
;
;pcc002 28-Dec-84 modules:cp4tt,cp4utl
; Add connect mode <esc>P command to toggle printer on
; and off. Conflicts with "official" recommended commands
; in protocol manual, but I don't think CP/M will ever get
; a PUSH command.
;
;pcc003-pcc005 2-Jan-85 vjc modules:cp4mit,cp4tt,cp4utl
; These edits must all be installed together and change the way
; logging is handled. The log file spec is moved to a separate
; fcb, and not opened until an actual CONNECT command is given.
; This takes care of a NASTY bug that if you used any other file
; command between the LOG and CONNECT, the log file would get
; written over the last file used. This also allows logging to
; be "permanently" enabled until an CLOSE (new command) for all
; CONNECT sessions, like most other kermits do. If a log file
; already exists, it will be appended to. Also add two new
; CONNECT mode commands <esc>Q to suspend logging and <esc>R to
; resume. <esc>R means something else during TRANSMIT, but
; logging is never on then, so there shouldn't be any conflict.
; I also changed the write code, so that it can handle one more
; character after the XOFF is send to stop the host. This allows
; a little "slop" for systems that don't stop immediately (such
; as TOPS10), but it didn't help much.
;
;pcc008 2-Jan-85 vjc modules:cp4def,cp4tt,cp4utl
; Keyboard input during CONNECT mode can get locked out if
; there is enough input from the modem port to keep prtchr
; busy. This can happen for example, if the printer is running
; at the same speed as the modem line, leaving you helpless to
; turn it off or abort the host. Add a fairness count, so that
; at least every prfair characters we look at console input.
;
;pcc012 4-Jan-85 vjc modules:cp4mit,cp4tt,cp4utl
; Use the big buffer for the log file. Move the log file back
; into the common fcb and only save the drive, name, and
; extension between connects. Add new routines to cp4utl to
; create or append to an existing file, and to conditionally
; advance buffers only if in memory. Remove edit pcc003 that
; allows one more character after the xoff, since it didn't
; really work very well and does not fit in well with the way
; the buffer advancing routines are set up. If someone still
; thinks this would be useful, it could be put back in with a
; little more work.
;
; While testing this edit, I also noticed another bug that
; the command parsing routines do not limit or check the
; length of command lines or file specs, trashing what ever
; comes after them. Currently because of where the fcb and
; command buffer are located, this does not usually cause a
; problem, but could if an extremely long line was typed in,
; or in the future multiple fcbs defined elsewhere in memory
; were used. Maybe this should be put on the bug list
; somewhere.
;
; edit 3: July 27, 1984
; Allow assembly with LASM: to CP4TT is linked by CP4PKT, and links
; to CP4CPM; remove exclamation points so as not to confuse LASM.
; Add Toad Hall TACtrap to TRANSMIT command (TAC intercept character
; is only doubled if it's data; when typed by the user, they're not
; automatically doubled)
;
; edit 2: June 7, 1984
; formatting and documentation; add module version number; make sure
; console is selected when leaving intchr.
;
; edit 1: May, 1984
; extracted from CPMBASE.M80 version 3.9; modifications are described
; in the accompanying .UPD file.
ttver: db 'CPSTT.ASM (12) 31-Jan-1991$'
; This is the TRANSMIT command. It attempts to send a file, even
; though there is no KERMIT on the other side.
; here from: kermit
;
; [OBS] I have replaced the routine, so that TRANSMIT <filename> <wait string>
; will send a line at a time to the host in a manner similar to MSKERMIT
;
;
xmit: mvi a,cmofi ;Parse an input file spec (non-wild).
lxi d,fcb ;Give the address for the FCB.
call comnd
jmp kermit ;Give up on bad parse.
;
lxi d,stbuff ; where to put the string
mvi a,cmtxt ; get text
call comnd
jmp kermit ; not quite correct...
sta strcnt ; string count returned in a
ana a ; if its zero, make it 1 character (CR)
jnz xmit0
mvi a,1
sta strcnt
mvi a,cr
sta stbuff
;
xmit0: call cfmcmd
call getfil ;Open file.
cpi 0FFH ;Succeed?
jnz xmit1
lxi d,erms15
call prtstr ;Display error msg.
jmp kermit
;
; New TRANSMIT routine - transmit a file, line by line, to a remote host
; waiting each time for one or more characters to be returned
; as a remote host prompt. It could be as simple as a CR or LF
; character. Repeat until the complete file has been sent, then
; close the transmitted file, and drop into the connect state so the
; user can tidy up at the host end.
;get the file to send, open it up, and read first sector from disk
xmit1: lxi d,inms19 ; say we are send a file to the host
call prtstr
xra a
sta repcnt ; clear the host prompt chars. counter
sta starc ; clear star count
;[MF][12]Delete the following call to "inbuf" as the call to "getfil"
;[MF][12]above will have initialized counters and flags so that when
;[MF][12]"in1chr" is called, "inbuf" will be called immediately and will
;[MF][12]immediately read from disk. Counters and flags will then be
;[MF][12]properly set up to read all characters of the file to be
;[MF][12]transmitted.
; call inbuf ; read one sector from disk
; jmp xmtex ; exit if error
xmt10: xra a ; clear retransmit flag and count etc
sta rexbfl ; retransmit flag (1=> retransmit)
sta rexcnt ; character counter
xmt1: call xmt1ch ; send a character
ani 7fh ; strip any parity
cpi cr ; have we reached the end of the line
jnz xmt1 ; nope, loop around again
; Now wait for a string back from the host. Compare with STRING buffer
;
xra a ; clear the character count
sta rexcnt
;
call selcon ; sent a line, send a star to console
mvi e,'*'
call outcon
lda starc ; update star count
inr a
sta starc
cpi 60 ; sent 60 stars?
jnz xmt1a ; nope...
xra a
sta starc
call prcrlf
xmt1a:
xmt3: lda eoflag ; have we hit end of file?
ana a
jnz xmtex ; yup, so quit.
xra a
sta repcnt ; clear the host prompt chars.counter
xmt2: call rd1chl ; read a character from the line
ani 7fh ; set flags
jnz xmt4 ; Not zero => we have a character from host
call ckchr ; see if *WE* have a character from console
push psw ; restore to modem
call selmdm
pop psw
ani 7fh ; stip parity (should not be there)
jnz xmt2a ; if a null, try again
lda strcnt ; if the string length is zero, dont wait.
ana a
jz xmt1 ; so loop back again
jmp xmt4 ; else test for xon/off and incomming string
xmt2a: cpi cntlc ; do we want to abort?
jz xmtex ; in which case drop through to connect mode
cpi cntlz ; if control z exit back to command loop
jnz xmt2b ; else try for other characters
lxi d,fcb ; close file before exiting to command loop
mvi c,closf
call bdos
jmp kermit
xmt2b: cpi cr ; a cr => resend last line
jnz xmt2 ; nope, then ignore it
mvi a,1
sta rexbfl ; else we want to resend the line.
jmp xmt1
xmt4: jmp xmt6 ; skit xoff test for now...*****************
cpi xoff ; xoff from host?
jnz xmt6
xmt5: call rd1chl ; else see if XOFF comming
ani 7fh
jnz xmt6 ; assume an xoff
call ckchr ; anything at console?
push psw
call selmdm
pop psw
ani 7fh
cpi cntlc ; control-c == abort & play terminal
jz xmtex
ana a ; anything else?
jz xmt5 ;loop again
xmt6: mov e,a ; save it for a while
lda repcnt ; see if this character matches with one in buffer
lxi h,stbuff ; point to string buffer
add l ; make hl = hl + a
mov l,a
mvi a,0
adc h
mov h,a ; not using xra, as that clears the Carry flag
mov a,e ; get the character back again
cmp m ; is it = to what we expect?
jnz xmt3 ; no, clear counter and try again
lda repcnt ; yes, then update the pointer, and ...
inr a ; ... see if we have received all ...
sta repcnt ; ... we should have received
mov e,a ; save length into E again
lda strcnt ; get the length to compare
sub e ; if (e) > string length, we have it
jz xmt10 ; so send next line (clear counters etc)
jmp xmt2 ; else wait for a little longer
;
; Routine below sends a character to the line. It sends up to a CR, and then
; it waits for a reply. This routine is called from xmt1, so if at
; end of file, return. Then XMT1 will drop through
; to connect.
xmt1ch: ; send a character from the xmtbuf to the line
call selmdm ; just in case it uses it
lda eoflag ; have we hit end of file
ana a ; set flags
jnz xmt1c1 ; no, so dont...
mvi a,cr ; load up a carriage return
xmt1c1: call get1xc ; get the character to send
cpi lf ; dont send line feeds
; jz xmt1c1
cpi cntlz ; if control z, then we are at end of the file
jz xmtex ; so close the file and drop into telcon
cpi 20h ; control character?
jp xmt11 ; no, so ok
cpi cr ; cr, and tabs ok to send
jz xmt11
cpi tab
jz xmt11
jmp xmt1c1 ; else try for another character
xmt11: call setpar ; else set parity etc
push psw ; we want to keep this for a while
mov e,a ; we need character in e
call outmdm
pop psw ; restore the character we sent
mov e,a ; now, if a TAC is set on..
lda tacflg
ana a
mov a,e ; (return must have sent character in a)
jz xmt1c2 ; test for xon/off
lda tacchr ;... get the tac character
cmp e ; do we send it again?
jnz xmt1c2 ; test for xon/off
push psw ; save character for return. Already set E...
call outmdm
pop psw
xmt1c2: ret
get1xc: ; get a character from the sector or re-transmit buffer read
; into a. Read a new sector if we run out.
;
; First, see if we do a retransmit
lda rexbfl
ana a ; if zero, a genuine line
jz get1x1
; have to retransmit a line
lxi h,rexbuf
lda rexcnt ; add counter to buffer base
mvi d,0
mov e,a
dad d
inr a ; update pointer
sta rexcnt
mov a,m ; get next character to send
ret ; and exit
get1x1: call in1chr ; get a character from the file.
mov c,a ; save it to the retransmit buffer
lda rexcnt
mov e,a
mvi d,0
lxi h,rexbuf
dad d ; point to next position
inr a
sta rexcnt ; update the character pointer
mov a,c ; restore character to a
mov m,c ; get character to c
ret
; read a character from the line.
rd1chl:
call selmdm ; select the modem
call inpmdm ; get input from the modem
ani 7fh ; strip parity
; may UPPERCASE-ify if case sensitivity off
ret ; return to caller
; End of transmit routine. Close input file name, and say we are dropping
; throught to telnet. Note that if eof not found, it is assumed that
; this is the ABORT exit.
xmtex:
lxi d,fcb ; close the transmitted file
mvi c,closf
call bdos
call selcon ; make sure we are talking to the console
lda eoflag ; end of file or abort exit?
lxi d,inms22 ; assume eof...
ana a
jz xmtex1
lxi d,inms29 ; we were wrong, its an abort.
xmtex1: jmp telnt1 ; and drop through to connect mode
; telnet does the printing
;
; telnet - the CONNECT command.
; here from: kermit
; telnt1 - entry to connect mode from TRANSMIT command
; here from: xend
telnet: call cfmcmd
lxi d,infms7 ;Output start of message
; enter here from TRANSMIT command.
telnt1: call prtstr
call escpr ;Print the escape char.
lxi d,infms8 ;Output some more of the message
call prtstr
call escpr ;Print the escape char again.
lxi d,inms8a ;Print the remainder of the message
call prtstr
call syscon ;do system-dependent stuff
lda logflg ;[pcc005] Want a log?
ora a ;[pcc005]
cnz logopn ;[pcc005] Open if so
chrlup: call prtchr ;See if char at port (send to console).
call conchr ;See if char at console (send to port).
jmp kermit ;requested to end session - go to command loop.
jmp chrlup ;Go do it again.
;
;
; prtchr - copy characters from comm line to console
; returns: nonskip, console selected.
; called by: xnext, rexmit, telnet
;
prtchr: call selmdm ; select modem port
call inpmdm ; try to get a character from it
push psw ; restore to console
call selcon ; select console
pop psw ; restore the (possible character) read
ora a ; test character
jnz prtch0 ; if non-zero, process it.
sta prtcnt ;[pcc008] zero out prt fairness count
ret ; return.
prtch0: ani 7FH ; drop parity bit.
sta comchr ;[6] save it in case we need it again
lda vtflg ;[9] get the vt52 emulation flag
cpi vtdefe ;[9] are we doing external emulation?
lda comchr ;[9] collect character again
jz extern ;[9] jup, go do it.
ana a ; set flags. it may be a null
jz prtchr ; ignore null (filler)
cpi del ; ignore delete, too
jz prtchr
cpi xon ;Is it an XON?
jz prtxon ;yes
cpi xoff ;Is it an XOFF?
jz prtxof ;yes
mov e,a ;Set the char aside.
lda vtflg ;Get the VT52 emulation flag.
cpi vtdefv ;Is the flag set for VT52 (ie 1)
;0 = none
;1 = VT52
;2 = external
;3 = dumb (traps non printing chars)
;0ffh not possible by local code (Will change)
jnz prtch1 ;If not, don't do this stuff.
lda escflg ;Get the escape flag.
ora a ;Are we working on an escape sequence?
jz prtch2 ;If not, continue.
call vt52 ;If so, work on it some more
jmp prtchr ;try for more characters.
prtch2: mov a,e ;normal text.
cpi esc ;Is the char an escape?
jnz prtch1 ;If not skip on.
mvi a,1
sta escflg ;Set the escape flag: escape seen.
jmp prtchr ;Get another char...
prtch1: cpi vtdefe ; are we doing external emulation?
jnz prtch3 ; assume we continue on
lxi h,extern+1 ; get address of external emulator
mov a,h ; se if address = 0 (not implemented)
ora l
jz prtch3 ; not external, assume we just carry on
pchl ; go do external emulation. RET back to caller
prtch3: cpi vtdefd ; are we trapping all non printing characters?
jnz prtch4 ; nope, something else
lda comchr ; Dumb terminal. Lets test the character
cpi cr ; cr then ok
jz prtch4 ; its ok
cpi lf ; lf then ok
jz prtch4
cpi tab
jz prtch4 ; assume tabs are expanded
cpi space ; if less than 20H ignore it
rm ; return if a control character
prtch4: call sysflt ; ok to print this character (in E)?
ora a
jz prtchr ; no, skip it.
lda logflg ;Get the log flag.
cpi 81H ;[pcc003] Are we logging
cz logit ;[pcc003] Do so if needed
call selcon ; select console
lda prnflg ;Get Print parallel flag
ora a
cnz outlpt ; output to printer if flag set
call outcon ; output to console.
lxi h,prtcnt ;[pcc008] point to prt fairness count
inr m ;[pcc008] bump
mov a,m ;[pcc008] get it in a
cpi prfair+1 ;[pcc008] time to be fair?
jm prtchr ;[pcc008] no, go around again.
mvi m,0 ;[pcc008] reset count
lda comchr ;[6] restore that character read from comm line
ret ;[pcc008] and return
; I don't think we want to print xon/xoff - this should be
; flow control only across the link between us and the host.
; (besides, IBM host xon's don't make sense to most micros)
; remember xon/xoff state in xofflg (zero = xon, non-zero = xoff)
prtxon: xra a ;Yes, reset XOFF flag
prtxof: sta xofflg
jmp prtchr ; look for another character
;;[pcc005] Log file routines
;[pcc005]
; logopn - open the log file
; Open the log file and append to it if it already exists
; or create one if not.
logopn:
mvi a,ctrlz ;[9] ignore control-z in log files
cmp e ;[9] well, was it?
rz ;[9] yes, to ignore it.
lxi h,lognam ;[pcc012] copy name
lxi d,fcb ;[pcc012] to fcb
lxi b,12 ;[pcc012] 12 bytes
call mover ;[pcc012] copy it
call appfil ;[pcc012] open file for appending
jmp logerr ;[pcc012] error
lxi h,logflg ;[pcc005] point to log flag
mvi a,80H ;[pcc005] file open flag
ora m ;[pcc005] or in contents of logflg
mov m,a ;[pcc005] and store back
lxi d,inms28 ;[pcc005] assume logging is on
cpi 81H ;[pcc005] check
jz prtstr ;[pcc005] print msg if true
lxi d,inms27 ;[pcc005] no, must be suspended
jmp prtstr ;[pcc005] print and return
;
; logit - output character in E to log file.
; we assume the host recognizes xon/xoff. (we probably shouldn't)
; modem port is selected.
; preserves de
; called by: prtchr
logit: lxi h,chrcnt ;[pcc012] point to buffer count
dcr m ;[pcc012] and decrement
jp logit1 ;[pcc012] continue if ok
push d ;[pcc012] save de
call outadv ;[pcc012] advance buffer if in memory
call logwrt ;[pcc012] sigh, time to write to disk
pop d ;[pcc012] restore de
lda logflg ;[pcc012] get logging flag
ora a ;[pcc012] Did we quit because of an error
rz ;[pcc012] return now if so
logit1: lhld bufpnt ;[pcc012] get buffer pointer
mov m,e ;Store the char.
inx h
shld bufpnt
ret ;[pcc012] and return
;[pcc012]
; logwrt - write to log file with XON/XOFF since it may take a while.
logwrt: call sndxoff ;[7] send and xoff to host
call outbuf ;[pcc012] output the buffer and advance
call logerr ;[pcc005] quit if error
call sndxon ;[send an xon to host
ret ;[pcc012]
;[pcc005]
; logcls - Close the log file and reset the flag
logcls: lxi d,infms6 ;[pcc005] Tell user we are closing file.
call prtstr ;[pcc005]
call clofil ;[pcc012] and do it
jmp logerr ;[pcc005] jump if error
lxi h,logflg ;[pcc005] point to flag
mov a,m ;[pcc005] get it
ani 7FH ;[pcc005] clear the open bit
mov m,a ;[pcc005] and store back
ret ;[pcc005]
;[pcc005]
; logerr - here on a variety of logging errors
; just close the file and disable logging
; called from logopn,logptr,logcls
logerr: lxi d,erms22 ;[pcc005] Error message
call prtstr ;[pcc005] print it
mvi c,closf ;[pcc005] Close the file.
lxi d,fcb ;[pcc012]
call bdos ;[pcc005]
xra a ;[pcc005] clear logflg
sta logflg ;[pcc005] so don't try again
ret ;[pcc005]
;
;
; VT52 emulation.
; called by: prtchr
; A/ contents of escflg (guaranteed non-zero)
; E/ current character
; modem is selected.
;
vt52: cpi 1 ; first character after escape?
jnz vt52y ; no, must be doing cursor positioning.
;
; E contains the character that followed the escape.
; valid characters are:
; A - cursor up
; B - cursor down
; C - cursor right
; D - cursor left
; F - enter graphics mode (hard to do on a non-vt52)
; G - exit graphics mode
; H - home
; I - reverse linefeed
; J - erase to end of screen
; K - erase to end of line
; Y - cursor positioning leadin
; Z - identify terminal as VT52
; [ - enter hold-screen mode (not supported)
; \ - exit hold-screen mode (not supported)
; > - enter alternate-keypad mode? (not supported)
; = - exit alternate-keypad mode? (not supported)
;
; Invalid sequences are handled as the VT52 does - the escape and
; the following character are swallowed, never to be seen again.
; For <esc>E, the translation table may contain just '$' (no action),
; or may be used as clear-and-home, as in the Heath/Zenith H19.
;
mov a,e ; get the second character of the sequence.
cpi 'Y' ; if cursor lead-in handle it.
jnz vt52a ; if not, go on.
mvi a,2 ; state = 2: row follows.
sta escflg ; update the flag.
ret ; back for another character
vt52a: cpi 'Z' ; VT52 ID query?
jz vt52id ; yes. claim to be one.
cpi 'A' ;Less than an 'A'?
jm vtig ;Yes - ignore.
cpi 'K'+1 ;Greater than 'K'?
jp vtig ;Yes - ignore.
sui 'A' ;Else make into index.
rlc ;Multiply by four.
rlc ;(Shift left twice.)
lhld pttab ;Load base addr of table.
mov e,a ;Move a into de pair.
mvi d,00H ;Zero out high byte.
dad d ;Double add index+offset.
xchg ;Exchange de with hl.
call selcon ; select console
call prtstr ;and syscall.
vtig: ;Ignore escape sequence.
xra a ;Reset the ol' escape flag.
sta escflg
ret ;Return home.
; here for <esc>Z. Tell the host we're a VT52. (Sure we are...)
vt52id: mvi a,esc ; response is escape...
call setpar ; (need correct parity)
mov e,a
call outmdm ; (console already selected)
mvi a,'/' ; ... slash ...
call setpar ; (with parity)
mov e,a
call outmdm
mvi a,'K' ; ... K.
call setpar
mov e,a
call outmdm
jmp vtig ; clear escape-sequence flag and return.
; here when escflg isn't 0 or 1 - processing cursor positioning sequence.
vt52y: cpi 2 ; looking for row? (y-coordinate)
jnz vt52x ; no, must be column.
mov a,e ; yes. get coordinate
sui (' '-1) ; convert from ascii (1 = top line)
sta vtyval ; store for later
mvi a,3 ; advance to next state (x coord)
sta escflg ; store it
ret ; try for another character
; here when escflag isn't 0, 1, or 2 - it must be 3. (right?)
; E holds the last character of the cursor positioning sequence.
vt52x: xra a ; end of escape sequence, reset state.
sta escflg
mov a,e ; get column (' ' is left margin)
sui (' '-1) ; make left margin be one
mov c,a ; stash column in c
lda vtyval ; get row number
mov b,a ; in b
call selcon ; select console
call csrpos ; call system-dependent cursor positioner
ret ; all through.
;
;
; conchr - copy character from console to comm line, processing
; (kermit's) escape sequences.
; Enter and exit with console selected.
; nonskip return: transparent mode terminated.
; skip return: still in transparent mode.
; called by: rexmit, telnet
conchr: call inpcon ;Try to get a character from the console
ani 07FH ;Keep only 7 bits
jz rskp ;Null means nothing there.
mov e,a ;Move the char for comparison.
sta lstchr ;Save it
lda escchr ;Get the escape char.
cmp e ;Is it an escape char?
jz intchr ;If so go process it.
call selmdm ; select the modem
mov a,e ;Get the char.
call setpar ;Set parity (if any).
mov e,a ;Restore it.
push d ; need to save e in case we are half dplx [5]
call outmdm ;Output the char to the port.
pop d ; Just in case we are half dplx [5]
call selcon ; reselect console
lda ecoflg ;Get the echo flag.
ora a ;Is it turned on?
jz rskp ;If not we're done here.
mov a,e ;Get the char.
ani 7FH ;Turn off the parity bit.
mov e,a
call outcon ; echo the character.
jmp rskp ; use skip return
;
; transparent escape character has been typed. dispatch on second
; character. (console is still selected)
; here from: conchr
intchr: call inpcon ; get another character from the console
ora a ; zero means no character available yet.
jz intchr ; If so, loop until we get a char.
mov b,a ;Save the actual char.
cpi ctrlc ;is it Control-C?
jz contc ;yes
ani 137O ;Convert to upper case.
cpi 'C' ;Is it close?
jnz intch0 ;If not proceed.
contc: lxi d,infms9 ;Say we are back.
call prtstr
call syscls ; call system-dependent close routine
lda logflg ;Get the log flag.
ora a ;[pcc005] Check if open
cm logcls ;[pcc005] Close if needed
ret
;Here if not a 'C' or '^C'
intch0: cpi 'S' ;Is it status?
jnz inch01 ;If not, proceed.
call stat01 ;Print out the status stuff.
call prcrlf ;[pcc011] add a crlf
jmp rskp ;return from conchr
inch01:
inch03: mov a,b ;Get the char.
cpi '?' ;Is it a help request?
jnz intch1 ;If not, go to the next check.
inch3a: lda logflg ;[pcc003] Logging flag
ora a ;[pcc003] see if active
jp inch04 ;[pcc005] jump if no file open
lxi d,loghlp ;[pcc003] yes, tell about R AND Q
call prtstr ;[pcc003]
inch04: lxi d,inthlp ;If so, get the address of the help message.
call prtstr
call sysinh ; print system-dependent help message
lxi d,inhlp1 ; Tell about doubling the escape character
call prtstr
call escpr ;Print escape character
lxi d,inhlp2 ;Print the rest
call prtstr
jmp intchr ;Get another char.
intch1: mov a,b ;Get the character.
cpi '0' ;Is it '0', to send a null?
jnz intch3 ;No.
xra a ;Yes, send an ASCII zero.
call setpar ; with the correct parity
mov e,a
call selmdm ; (to the modem...)
call outmdm
call selcon ; return with console selected
jmp rskp
intch3: lda escchr ;Get the escape char.
cmp b ;Is it the escape char?
jnz intch4 ;[pcc002] jump if not
mov a,b ;Get the char.
call setpar
mov e,a ;Restore it.
call selmdm
call outmdm ;Output it.
call selcon ;We promised console would be selected...
jmp rskp ;Return, we are done here.
intch4: mov a,b ;[pcc002] get it again
ani 137o ;[pcc002] in upper case
cpi 'P' ;[pcc002] toggle printer?
jnz intch5 ;[pcc003] nope
lda prnflg ;[pcc002] get printer flag
xri 01h ;[pcc002] complement it
sta prnflg ;[pcc002] and put back
jmp rskp ;[pcc002]
intch5: lda logflg ;[pcc003] get log flag
ora a ;[pcc003] See if open
jp intch7 ;[pcc003] no, skip R and Q
mov a,b ;[pcc003] get back chr
ani 137o ;[pcc003] make upper case
cpi 'R' ;[pcc003] Is it R
jnz intch6 ;[pcc003] Jump if not
mvi a,81H ;[pcc003] set flag for logging
sta logflg ;[pcc003] put it back
lxi d,inms28 ;[pcc003] message
call prtstr ;[pcc003]
jmp rskp ;[pcc003] done
intch6: cpi 'Q' ;[pcc003] Quit logging?
jnz intch7 ;[pcc003] no
mvi a,82H ;[pcc003] flag for open, but suspended
sta logflg ;[pcc003] store away
lxi d,inms27 ;[pcc003] keep them informed
call prtstr ;[pcc003]
jmp rskp ;[pcc003]
intch7: ;[pcc003]
intchz: mov a,b ; not recognized. get saved copy back.
push psw ;[8] save as we will want to test for 'D'
call sysint ; interpret system-dependent sequences
jmp intchy ; done. [10] Now see if D. If so, do a C.
pop psw ;[10] tidy stack
mvi e,'G'-100O ;Otherwise send a beep.
call outcon ; to the console.
jmp rskp
intchy: pop psw ;[10] adjust stack
ani 5fh ;[10] strip parity, make it upper case
cpi 'D' ;[10] was it a D?
jz contc ;[10] yup, so to the equivalent of an escape-C
jmp rskp
;
; Little code to allow some expansion of code without changing
; every futher address, only up to the end of this file.
; TO BE REMOVED FOR RELEASE!
; org ($+100h) AND 0FF00H
IF lasm
LINK CPSCPM
ENDIF;lasm