diff options
| author | Jeff Armstrong <jeff@approximatrix.com> | 2026-10-25 17:42:06 -0400 |
|---|---|---|
| committer | Jeff Armstrong <jeff@approximatrix.com> | 2026-10-25 17:42:06 -0400 |
| commit | ebb2ff2af569d5822b70ee555a32d27cf7494816 (patch) | |
| tree | 7ac5e7b3fa73f7a8d996129086932ecce66374ad /src/cpstt.asm | |
| download | kermit-80-ebb2ff2af569d5822b70ee555a32d27cf7494816.tar.gz kermit-80-ebb2ff2af569d5822b70ee555a32d27cf7494816.zip | |
Diffstat (limited to 'src/cpstt.asm')
| -rw-r--r-- | src/cpstt.asm | 862 |
1 files changed, 862 insertions, 0 deletions
diff --git a/src/cpstt.asm b/src/cpstt.asm new file mode 100644 index 0000000..41a30af --- /dev/null +++ b/src/cpstt.asm @@ -0,0 +1,862 @@ +; 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 |
