]> cloudbase.mooo.com Git - kermit-80.git/blob - cpstt.asm
Import of "Kermit 80 for CP/M-80 and CP/M-85" from http://www.columbia.edu/kermit...
[kermit-80.git] / cpstt.asm
1 ; CPSTT.ASM
2 ; KERMIT - (Celtic for "FREE")
3 ;
4 ; This is the CP/M-80 implementation of the Columbia University
5 ; KERMIT file transfer protocol.
6 ;
7 ; Version 4.0
8 ;
9 ; Copyright June 1981,1982,1983,1984,1985
10 ; Columbia University
11 ;
12 ; Originally written by Bill Catchings of the Columbia University Center for
13 ; Computing Activities, 612 W. 115th St., New York, NY 10025.
14 ;
15 ; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
16 ; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
17 ; others.
18 ;
19 ; This file contains the code for the TRANSMIT and CONNECT commands,
20 ; which communicate with a host which is not running KERMIT.
21 ;
22 ; revision history:
23 ;
24 ;edit 12, 31-Jan-1991 by MF. Delete call to "inbuf" after "xmit1" in
25 ; the TRANSMIT command. "getfil" initializes various counters so that
26 ; when "in1chr" is first called, "inbuf" will be called immediately
27 ; and will read sectors of the file to be transmitted from disk.
28 ; This, along with a fix to "in1chr" in CPSUTL.ASM, fixes a bug
29 ; discovered by Lance Tagliapietra of the University of Wisconsin at
30 ; Platteville wherein the TRANSMIT command was failing to transmit some
31 ; characters in files over one sector in length. See CPSUTL.ASM,
32 ; edit 29.
33 ; edit 11, 10 September, a987, by OBSchou. Modified TRANSMIT command
34 ; to TRANSMIT <file> <string>
35 ;
36 ; edit 10, 27 August, 1987 by OBSchou. Fixed bugs in Transmit, but I may
37 ; be introducing problems for IBM/CMS or half duplex systems. What
38 ; does this combination do??
39 ;
40 ; edit 9 30 March, 1987 by OBSchou to replace the TRANSMIT routine.
41 ; Syntax is now TRANSMIT file after a previous
42 ; INPUT <wait time> <string to wait for>
43 ;
44 ; edit 8 19 June, 1986 by OBSchou. Modified the interupt testing routine
45 ; to see if the command was a 'D' (Drop the line), in which case also
46 ; do a 'C', ie disconnect. This is really a little too much of a
47 ; system dependent thing.
48 ; For now, Ill leave it here, and possibly move it later.
49 ;
50 ; edit 7 30 May 1986 OBSchou. Moved xon/xoff control (ie XON/OFF sent to host)
51 ; out to CPSUTL so that ther printer routine can use it too.
52 ;
53 ; edit 6 30 April, 1986 by OBSchou.
54 ; Fixed transmit bug, so as soon as the protocol character is
55 ; received from the host is received then another line is sent.
56 ; added in a comchr (ds 1) to save the character read from the comm
57 ; line in prtchr, and is restored in a on return.
58 ;
59 ; edit 5 7 March, 1986 by OBSchou Loughborough University.
60 ; Need to save the E register before calling outmdm (in CPSSYS.ASM)
61 ; if doing Half duplex. Push/pop DE should sort this problem
62 ;
63 ; edit 4: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809
64 ;
65 ;pcc002 28-Dec-84 modules:cp4tt,cp4utl
66 ; Add connect mode <esc>P command to toggle printer on
67 ; and off. Conflicts with "official" recommended commands
68 ; in protocol manual, but I don't think CP/M will ever get
69 ; a PUSH command.
70 ;
71 ;pcc003-pcc005 2-Jan-85 vjc modules:cp4mit,cp4tt,cp4utl
72 ; These edits must all be installed together and change the way
73 ; logging is handled. The log file spec is moved to a separate
74 ; fcb, and not opened until an actual CONNECT command is given.
75 ; This takes care of a NASTY bug that if you used any other file
76 ; command between the LOG and CONNECT, the log file would get
77 ; written over the last file used. This also allows logging to
78 ; be "permanently" enabled until an CLOSE (new command) for all
79 ; CONNECT sessions, like most other kermits do. If a log file
80 ; already exists, it will be appended to. Also add two new
81 ; CONNECT mode commands <esc>Q to suspend logging and <esc>R to
82 ; resume. <esc>R means something else during TRANSMIT, but
83 ; logging is never on then, so there shouldn't be any conflict.
84 ; I also changed the write code, so that it can handle one more
85 ; character after the XOFF is send to stop the host. This allows
86 ; a little "slop" for systems that don't stop immediately (such
87 ; as TOPS10), but it didn't help much.
88 ;
89 ;pcc008 2-Jan-85 vjc modules:cp4def,cp4tt,cp4utl
90 ; Keyboard input during CONNECT mode can get locked out if
91 ; there is enough input from the modem port to keep prtchr
92 ; busy. This can happen for example, if the printer is running
93 ; at the same speed as the modem line, leaving you helpless to
94 ; turn it off or abort the host. Add a fairness count, so that
95 ; at least every prfair characters we look at console input.
96 ;
97 ;pcc012 4-Jan-85 vjc modules:cp4mit,cp4tt,cp4utl
98 ; Use the big buffer for the log file. Move the log file back
99 ; into the common fcb and only save the drive, name, and
100 ; extension between connects. Add new routines to cp4utl to
101 ; create or append to an existing file, and to conditionally
102 ; advance buffers only if in memory. Remove edit pcc003 that
103 ; allows one more character after the xoff, since it didn't
104 ; really work very well and does not fit in well with the way
105 ; the buffer advancing routines are set up. If someone still
106 ; thinks this would be useful, it could be put back in with a
107 ; little more work.
108 ;
109 ; While testing this edit, I also noticed another bug that
110 ; the command parsing routines do not limit or check the
111 ; length of command lines or file specs, trashing what ever
112 ; comes after them. Currently because of where the fcb and
113 ; command buffer are located, this does not usually cause a
114 ; problem, but could if an extremely long line was typed in,
115 ; or in the future multiple fcbs defined elsewhere in memory
116 ; were used. Maybe this should be put on the bug list
117 ; somewhere.
118 ;
119 ; edit 3: July 27, 1984
120 ; Allow assembly with LASM: to CP4TT is linked by CP4PKT, and links
121 ; to CP4CPM; remove exclamation points so as not to confuse LASM.
122 ; Add Toad Hall TACtrap to TRANSMIT command (TAC intercept character
123 ; is only doubled if it's data; when typed by the user, they're not
124 ; automatically doubled)
125 ;
126 ; edit 2: June 7, 1984
127 ; formatting and documentation; add module version number; make sure
128 ; console is selected when leaving intchr.
129 ;
130 ; edit 1: May, 1984
131 ; extracted from CPMBASE.M80 version 3.9; modifications are described
132 ; in the accompanying .UPD file.
133
134 ttver: db 'CPSTT.ASM (12) 31-Jan-1991$'
135
136 ; This is the TRANSMIT command. It attempts to send a file, even
137 ; though there is no KERMIT on the other side.
138 ; here from: kermit
139 ;
140 ; [OBS] I have replaced the routine, so that TRANSMIT <filename> <wait string>
141 ; will send a line at a time to the host in a manner similar to MSKERMIT
142 ;
143 ;
144 xmit: mvi a,cmofi ;Parse an input file spec (non-wild).
145 lxi d,fcb ;Give the address for the FCB.
146 call comnd
147 jmp kermit ;Give up on bad parse.
148 ;
149 lxi d,stbuff ; where to put the string
150 mvi a,cmtxt ; get text
151 call comnd
152 jmp kermit ; not quite correct...
153 sta strcnt ; string count returned in a
154 ana a ; if its zero, make it 1 character (CR)
155 jnz xmit0
156 mvi a,1
157 sta strcnt
158 mvi a,cr
159 sta stbuff
160 ;
161 xmit0: call cfmcmd
162 call getfil ;Open file.
163 cpi 0FFH ;Succeed?
164 jnz xmit1
165 lxi d,erms15
166 call prtstr ;Display error msg.
167 jmp kermit
168
169 ;
170 ; New TRANSMIT routine - transmit a file, line by line, to a remote host
171 ; waiting each time for one or more characters to be returned
172 ; as a remote host prompt. It could be as simple as a CR or LF
173 ; character. Repeat until the complete file has been sent, then
174 ; close the transmitted file, and drop into the connect state so the
175 ; user can tidy up at the host end.
176 ;get the file to send, open it up, and read first sector from disk
177
178 xmit1: lxi d,inms19 ; say we are send a file to the host
179 call prtstr
180
181 xra a
182 sta repcnt ; clear the host prompt chars. counter
183 sta starc ; clear star count
184 ;[MF][12]Delete the following call to "inbuf" as the call to "getfil"
185 ;[MF][12]above will have initialized counters and flags so that when
186 ;[MF][12]"in1chr" is called, "inbuf" will be called immediately and will
187 ;[MF][12]immediately read from disk. Counters and flags will then be
188 ;[MF][12]properly set up to read all characters of the file to be
189 ;[MF][12]transmitted.
190 ; call inbuf ; read one sector from disk
191 ; jmp xmtex ; exit if error
192
193
194 xmt10: xra a ; clear retransmit flag and count etc
195 sta rexbfl ; retransmit flag (1=> retransmit)
196 sta rexcnt ; character counter
197
198 xmt1: call xmt1ch ; send a character
199 ani 7fh ; strip any parity
200 cpi cr ; have we reached the end of the line
201 jnz xmt1 ; nope, loop around again
202
203 ; Now wait for a string back from the host. Compare with STRING buffer
204 ;
205 xra a ; clear the character count
206 sta rexcnt
207 ;
208 call selcon ; sent a line, send a star to console
209 mvi e,'*'
210 call outcon
211 lda starc ; update star count
212 inr a
213 sta starc
214 cpi 60 ; sent 60 stars?
215 jnz xmt1a ; nope...
216 xra a
217 sta starc
218 call prcrlf
219 xmt1a:
220
221 xmt3: lda eoflag ; have we hit end of file?
222 ana a
223 jnz xmtex ; yup, so quit.
224 xra a
225 sta repcnt ; clear the host prompt chars.counter
226 xmt2: call rd1chl ; read a character from the line
227 ani 7fh ; set flags
228 jnz xmt4 ; Not zero => we have a character from host
229 call ckchr ; see if *WE* have a character from console
230 push psw ; restore to modem
231 call selmdm
232 pop psw
233 ani 7fh ; stip parity (should not be there)
234 jnz xmt2a ; if a null, try again
235 lda strcnt ; if the string length is zero, dont wait.
236 ana a
237 jz xmt1 ; so loop back again
238 jmp xmt4 ; else test for xon/off and incomming string
239
240 xmt2a: cpi cntlc ; do we want to abort?
241 jz xmtex ; in which case drop through to connect mode
242 cpi cntlz ; if control z exit back to command loop
243 jnz xmt2b ; else try for other characters
244 lxi d,fcb ; close file before exiting to command loop
245 mvi c,closf
246 call bdos
247 jmp kermit
248
249 xmt2b: cpi cr ; a cr => resend last line
250 jnz xmt2 ; nope, then ignore it
251 mvi a,1
252 sta rexbfl ; else we want to resend the line.
253 jmp xmt1
254
255 xmt4: jmp xmt6 ; skit xoff test for now...*****************
256
257 cpi xoff ; xoff from host?
258 jnz xmt6
259 xmt5: call rd1chl ; else see if XOFF comming
260 ani 7fh
261 jnz xmt6 ; assume an xoff
262 call ckchr ; anything at console?
263 push psw
264 call selmdm
265 pop psw
266 ani 7fh
267 cpi cntlc ; control-c == abort & play terminal
268 jz xmtex
269 ana a ; anything else?
270 jz xmt5 ;loop again
271
272 xmt6: mov e,a ; save it for a while
273 lda repcnt ; see if this character matches with one in buffer
274 lxi h,stbuff ; point to string buffer
275 add l ; make hl = hl + a
276 mov l,a
277 mvi a,0
278 adc h
279 mov h,a ; not using xra, as that clears the Carry flag
280 mov a,e ; get the character back again
281 cmp m ; is it = to what we expect?
282 jnz xmt3 ; no, clear counter and try again
283 lda repcnt ; yes, then update the pointer, and ...
284 inr a ; ... see if we have received all ...
285 sta repcnt ; ... we should have received
286 mov e,a ; save length into E again
287 lda strcnt ; get the length to compare
288 sub e ; if (e) > string length, we have it
289 jz xmt10 ; so send next line (clear counters etc)
290 jmp xmt2 ; else wait for a little longer
291
292
293 ;
294 ; Routine below sends a character to the line. It sends up to a CR, and then
295 ; it waits for a reply. This routine is called from xmt1, so if at
296 ; end of file, return. Then XMT1 will drop through
297 ; to connect.
298 xmt1ch: ; send a character from the xmtbuf to the line
299 call selmdm ; just in case it uses it
300 lda eoflag ; have we hit end of file
301 ana a ; set flags
302 jnz xmt1c1 ; no, so dont...
303 mvi a,cr ; load up a carriage return
304 xmt1c1: call get1xc ; get the character to send
305 cpi lf ; dont send line feeds
306 ; jz xmt1c1
307 cpi cntlz ; if control z, then we are at end of the file
308 jz xmtex ; so close the file and drop into telcon
309 cpi 20h ; control character?
310 jp xmt11 ; no, so ok
311 cpi cr ; cr, and tabs ok to send
312 jz xmt11
313 cpi tab
314 jz xmt11
315 jmp xmt1c1 ; else try for another character
316
317 xmt11: call setpar ; else set parity etc
318 push psw ; we want to keep this for a while
319 mov e,a ; we need character in e
320 call outmdm
321 pop psw ; restore the character we sent
322 mov e,a ; now, if a TAC is set on..
323 lda tacflg
324 ana a
325 mov a,e ; (return must have sent character in a)
326 jz xmt1c2 ; test for xon/off
327 lda tacchr ;... get the tac character
328 cmp e ; do we send it again?
329 jnz xmt1c2 ; test for xon/off
330 push psw ; save character for return. Already set E...
331 call outmdm
332 pop psw
333
334 xmt1c2: ret
335
336 get1xc: ; get a character from the sector or re-transmit buffer read
337 ; into a. Read a new sector if we run out.
338 ;
339 ; First, see if we do a retransmit
340 lda rexbfl
341 ana a ; if zero, a genuine line
342 jz get1x1
343 ; have to retransmit a line
344 lxi h,rexbuf
345 lda rexcnt ; add counter to buffer base
346 mvi d,0
347 mov e,a
348 dad d
349 inr a ; update pointer
350 sta rexcnt
351 mov a,m ; get next character to send
352 ret ; and exit
353
354 get1x1: call in1chr ; get a character from the file.
355 mov c,a ; save it to the retransmit buffer
356 lda rexcnt
357 mov e,a
358 mvi d,0
359 lxi h,rexbuf
360 dad d ; point to next position
361 inr a
362 sta rexcnt ; update the character pointer
363 mov a,c ; restore character to a
364 mov m,c ; get character to c
365 ret
366
367
368
369 ; read a character from the line.
370 rd1chl:
371 call selmdm ; select the modem
372 call inpmdm ; get input from the modem
373 ani 7fh ; strip parity
374 ; may UPPERCASE-ify if case sensitivity off
375 ret ; return to caller
376
377 ; End of transmit routine. Close input file name, and say we are dropping
378 ; throught to telnet. Note that if eof not found, it is assumed that
379 ; this is the ABORT exit.
380
381 xmtex:
382 lxi d,fcb ; close the transmitted file
383 mvi c,closf
384 call bdos
385 call selcon ; make sure we are talking to the console
386
387 lda eoflag ; end of file or abort exit?
388 lxi d,inms22 ; assume eof...
389 ana a
390 jz xmtex1
391 lxi d,inms29 ; we were wrong, its an abort.
392 xmtex1: jmp telnt1 ; and drop through to connect mode
393 ; telnet does the printing
394
395
396
397 ;\f
398 ; telnet - the CONNECT command.
399 ; here from: kermit
400 ; telnt1 - entry to connect mode from TRANSMIT command
401 ; here from: xend
402
403 telnet: call cfmcmd
404 lxi d,infms7 ;Output start of message
405 ; enter here from TRANSMIT command.
406 telnt1: call prtstr
407 call escpr ;Print the escape char.
408 lxi d,infms8 ;Output some more of the message
409 call prtstr
410 call escpr ;Print the escape char again.
411 lxi d,inms8a ;Print the remainder of the message
412 call prtstr
413 call syscon ;do system-dependent stuff
414 lda logflg ;[pcc005] Want a log?
415 ora a ;[pcc005]
416 cnz logopn ;[pcc005] Open if so
417
418 chrlup: call prtchr ;See if char at port (send to console).
419 call conchr ;See if char at console (send to port).
420 jmp kermit ;requested to end session - go to command loop.
421 jmp chrlup ;Go do it again.
422 ;\f
423 ;
424 ; prtchr - copy characters from comm line to console
425 ; returns: nonskip, console selected.
426 ; called by: xnext, rexmit, telnet
427 ;
428
429 prtchr: call selmdm ; select modem port
430 call inpmdm ; try to get a character from it
431 push psw ; restore to console
432 call selcon ; select console
433 pop psw ; restore the (possible character) read
434 ora a ; test character
435 jnz prtch0 ; if non-zero, process it.
436 sta prtcnt ;[pcc008] zero out prt fairness count
437 ret ; return.
438
439 prtch0: ani 7FH ; drop parity bit.
440 sta comchr ;[6] save it in case we need it again
441 lda vtflg ;[9] get the vt52 emulation flag
442 cpi vtdefe ;[9] are we doing external emulation?
443 lda comchr ;[9] collect character again
444 jz extern ;[9] jup, go do it.
445
446 ana a ; set flags. it may be a null
447 jz prtchr ; ignore null (filler)
448 cpi del ; ignore delete, too
449 jz prtchr
450 cpi xon ;Is it an XON?
451 jz prtxon ;yes
452 cpi xoff ;Is it an XOFF?
453 jz prtxof ;yes
454 mov e,a ;Set the char aside.
455 lda vtflg ;Get the VT52 emulation flag.
456 cpi vtdefv ;Is the flag set for VT52 (ie 1)
457 ;0 = none
458 ;1 = VT52
459 ;2 = external
460 ;3 = dumb (traps non printing chars)
461 ;0ffh not possible by local code (Will change)
462 jnz prtch1 ;If not, don't do this stuff.
463 lda escflg ;Get the escape flag.
464 ora a ;Are we working on an escape sequence?
465 jz prtch2 ;If not, continue.
466 call vt52 ;If so, work on it some more
467 jmp prtchr ;try for more characters.
468
469 prtch2: mov a,e ;normal text.
470 cpi esc ;Is the char an escape?
471 jnz prtch1 ;If not skip on.
472 mvi a,1
473 sta escflg ;Set the escape flag: escape seen.
474 jmp prtchr ;Get another char...
475
476 prtch1: cpi vtdefe ; are we doing external emulation?
477 jnz prtch3 ; assume we continue on
478 lxi h,extern+1 ; get address of external emulator
479 mov a,h ; se if address = 0 (not implemented)
480 ora l
481 jz prtch3 ; not external, assume we just carry on
482 pchl ; go do external emulation. RET back to caller
483
484 prtch3: cpi vtdefd ; are we trapping all non printing characters?
485 jnz prtch4 ; nope, something else
486 lda comchr ; Dumb terminal. Lets test the character
487 cpi cr ; cr then ok
488 jz prtch4 ; its ok
489 cpi lf ; lf then ok
490 jz prtch4
491 cpi tab
492 jz prtch4 ; assume tabs are expanded
493 cpi space ; if less than 20H ignore it
494 rm ; return if a control character
495
496 prtch4: call sysflt ; ok to print this character (in E)?
497 ora a
498 jz prtchr ; no, skip it.
499 lda logflg ;Get the log flag.
500 cpi 81H ;[pcc003] Are we logging
501 cz logit ;[pcc003] Do so if needed
502 call selcon ; select console
503 lda prnflg ;Get Print parallel flag
504 ora a
505 cnz outlpt ; output to printer if flag set
506 call outcon ; output to console.
507 lxi h,prtcnt ;[pcc008] point to prt fairness count
508 inr m ;[pcc008] bump
509 mov a,m ;[pcc008] get it in a
510 cpi prfair+1 ;[pcc008] time to be fair?
511 jm prtchr ;[pcc008] no, go around again.
512 mvi m,0 ;[pcc008] reset count
513 lda comchr ;[6] restore that character read from comm line
514 ret ;[pcc008] and return
515
516 ; I don't think we want to print xon/xoff - this should be
517 ; flow control only across the link between us and the host.
518 ; (besides, IBM host xon's don't make sense to most micros)
519 ; remember xon/xoff state in xofflg (zero = xon, non-zero = xoff)
520 prtxon: xra a ;Yes, reset XOFF flag
521 prtxof: sta xofflg
522 jmp prtchr ; look for another character
523 ;\f;[pcc005] Log file routines
524
525 ;[pcc005]
526 ; logopn - open the log file
527 ; Open the log file and append to it if it already exists
528 ; or create one if not.
529
530 logopn:
531 mvi a,ctrlz ;[9] ignore control-z in log files
532 cmp e ;[9] well, was it?
533 rz ;[9] yes, to ignore it.
534 lxi h,lognam ;[pcc012] copy name
535 lxi d,fcb ;[pcc012] to fcb
536 lxi b,12 ;[pcc012] 12 bytes
537 call mover ;[pcc012] copy it
538 call appfil ;[pcc012] open file for appending
539 jmp logerr ;[pcc012] error
540 lxi h,logflg ;[pcc005] point to log flag
541 mvi a,80H ;[pcc005] file open flag
542 ora m ;[pcc005] or in contents of logflg
543 mov m,a ;[pcc005] and store back
544 lxi d,inms28 ;[pcc005] assume logging is on
545 cpi 81H ;[pcc005] check
546 jz prtstr ;[pcc005] print msg if true
547 lxi d,inms27 ;[pcc005] no, must be suspended
548 jmp prtstr ;[pcc005] print and return
549
550 ;
551 ; logit - output character in E to log file.
552 ; we assume the host recognizes xon/xoff. (we probably shouldn't)
553 ; modem port is selected.
554 ; preserves de
555 ; called by: prtchr
556
557 logit: lxi h,chrcnt ;[pcc012] point to buffer count
558 dcr m ;[pcc012] and decrement
559 jp logit1 ;[pcc012] continue if ok
560 push d ;[pcc012] save de
561 call outadv ;[pcc012] advance buffer if in memory
562 call logwrt ;[pcc012] sigh, time to write to disk
563 pop d ;[pcc012] restore de
564 lda logflg ;[pcc012] get logging flag
565 ora a ;[pcc012] Did we quit because of an error
566 rz ;[pcc012] return now if so
567 logit1: lhld bufpnt ;[pcc012] get buffer pointer
568 mov m,e ;Store the char.
569 inx h
570 shld bufpnt
571 ret ;[pcc012] and return
572
573 ;[pcc012]
574 ; logwrt - write to log file with XON/XOFF since it may take a while.
575
576 logwrt: call sndxoff ;[7] send and xoff to host
577 call outbuf ;[pcc012] output the buffer and advance
578 call logerr ;[pcc005] quit if error
579 call sndxon ;[send an xon to host
580 ret ;[pcc012]
581
582 ;[pcc005]
583 ; logcls - Close the log file and reset the flag
584
585 logcls: lxi d,infms6 ;[pcc005] Tell user we are closing file.
586 call prtstr ;[pcc005]
587 call clofil ;[pcc012] and do it
588 jmp logerr ;[pcc005] jump if error
589 lxi h,logflg ;[pcc005] point to flag
590 mov a,m ;[pcc005] get it
591 ani 7FH ;[pcc005] clear the open bit
592 mov m,a ;[pcc005] and store back
593 ret ;[pcc005]
594
595 ;[pcc005]
596 ; logerr - here on a variety of logging errors
597 ; just close the file and disable logging
598 ; called from logopn,logptr,logcls
599
600 logerr: lxi d,erms22 ;[pcc005] Error message
601 call prtstr ;[pcc005] print it
602 mvi c,closf ;[pcc005] Close the file.
603 lxi d,fcb ;[pcc012]
604 call bdos ;[pcc005]
605 xra a ;[pcc005] clear logflg
606 sta logflg ;[pcc005] so don't try again
607 ret ;[pcc005]
608 ;\f
609 ;
610 ; VT52 emulation.
611 ; called by: prtchr
612 ; A/ contents of escflg (guaranteed non-zero)
613 ; E/ current character
614 ; modem is selected.
615 ;
616 vt52: cpi 1 ; first character after escape?
617 jnz vt52y ; no, must be doing cursor positioning.
618 ;
619 ; E contains the character that followed the escape.
620 ; valid characters are:
621 ; A - cursor up
622 ; B - cursor down
623 ; C - cursor right
624 ; D - cursor left
625 ; F - enter graphics mode (hard to do on a non-vt52)
626 ; G - exit graphics mode
627 ; H - home
628 ; I - reverse linefeed
629 ; J - erase to end of screen
630 ; K - erase to end of line
631 ; Y - cursor positioning leadin
632 ; Z - identify terminal as VT52
633 ; [ - enter hold-screen mode (not supported)
634 ; \ - exit hold-screen mode (not supported)
635 ; > - enter alternate-keypad mode? (not supported)
636 ; = - exit alternate-keypad mode? (not supported)
637 ;
638 ; Invalid sequences are handled as the VT52 does - the escape and
639 ; the following character are swallowed, never to be seen again.
640 ; For <esc>E, the translation table may contain just '$' (no action),
641 ; or may be used as clear-and-home, as in the Heath/Zenith H19.
642 ;
643 mov a,e ; get the second character of the sequence.
644 cpi 'Y' ; if cursor lead-in handle it.
645 jnz vt52a ; if not, go on.
646 mvi a,2 ; state = 2: row follows.
647 sta escflg ; update the flag.
648 ret ; back for another character
649
650 vt52a: cpi 'Z' ; VT52 ID query?
651 jz vt52id ; yes. claim to be one.
652 cpi 'A' ;Less than an 'A'?
653 jm vtig ;Yes - ignore.
654 cpi 'K'+1 ;Greater than 'K'?
655 jp vtig ;Yes - ignore.
656 sui 'A' ;Else make into index.
657 rlc ;Multiply by four.
658 rlc ;(Shift left twice.)
659 lhld pttab ;Load base addr of table.
660 mov e,a ;Move a into de pair.
661 mvi d,00H ;Zero out high byte.
662 dad d ;Double add index+offset.
663 xchg ;Exchange de with hl.
664 call selcon ; select console
665 call prtstr ;and syscall.
666 vtig: ;Ignore escape sequence.
667 xra a ;Reset the ol' escape flag.
668 sta escflg
669 ret ;Return home.
670
671 ; here for <esc>Z. Tell the host we're a VT52. (Sure we are...)
672 vt52id: mvi a,esc ; response is escape...
673 call setpar ; (need correct parity)
674 mov e,a
675 call outmdm ; (console already selected)
676 mvi a,'/' ; ... slash ...
677 call setpar ; (with parity)
678 mov e,a
679 call outmdm
680 mvi a,'K' ; ... K.
681 call setpar
682 mov e,a
683 call outmdm
684 jmp vtig ; clear escape-sequence flag and return.
685
686 ; here when escflg isn't 0 or 1 - processing cursor positioning sequence.
687 vt52y: cpi 2 ; looking for row? (y-coordinate)
688 jnz vt52x ; no, must be column.
689 mov a,e ; yes. get coordinate
690 sui (' '-1) ; convert from ascii (1 = top line)
691 sta vtyval ; store for later
692 mvi a,3 ; advance to next state (x coord)
693 sta escflg ; store it
694 ret ; try for another character
695
696 ; here when escflag isn't 0, 1, or 2 - it must be 3. (right?)
697 ; E holds the last character of the cursor positioning sequence.
698 vt52x: xra a ; end of escape sequence, reset state.
699 sta escflg
700 mov a,e ; get column (' ' is left margin)
701 sui (' '-1) ; make left margin be one
702 mov c,a ; stash column in c
703 lda vtyval ; get row number
704 mov b,a ; in b
705 call selcon ; select console
706 call csrpos ; call system-dependent cursor positioner
707 ret ; all through.
708 ;\f
709 ;
710 ; conchr - copy character from console to comm line, processing
711 ; (kermit's) escape sequences.
712 ; Enter and exit with console selected.
713 ; nonskip return: transparent mode terminated.
714 ; skip return: still in transparent mode.
715 ; called by: rexmit, telnet
716
717 conchr: call inpcon ;Try to get a character from the console
718 ani 07FH ;Keep only 7 bits
719 jz rskp ;Null means nothing there.
720 mov e,a ;Move the char for comparison.
721 sta lstchr ;Save it
722 lda escchr ;Get the escape char.
723 cmp e ;Is it an escape char?
724 jz intchr ;If so go process it.
725 call selmdm ; select the modem
726 mov a,e ;Get the char.
727 call setpar ;Set parity (if any).
728 mov e,a ;Restore it.
729 push d ; need to save e in case we are half dplx [5]
730 call outmdm ;Output the char to the port.
731 pop d ; Just in case we are half dplx [5]
732 call selcon ; reselect console
733 lda ecoflg ;Get the echo flag.
734 ora a ;Is it turned on?
735 jz rskp ;If not we're done here.
736 mov a,e ;Get the char.
737 ani 7FH ;Turn off the parity bit.
738 mov e,a
739 call outcon ; echo the character.
740 jmp rskp ; use skip return
741 ;\f
742 ; transparent escape character has been typed. dispatch on second
743 ; character. (console is still selected)
744 ; here from: conchr
745
746 intchr: call inpcon ; get another character from the console
747 ora a ; zero means no character available yet.
748 jz intchr ; If so, loop until we get a char.
749 mov b,a ;Save the actual char.
750 cpi ctrlc ;is it Control-C?
751 jz contc ;yes
752 ani 137O ;Convert to upper case.
753 cpi 'C' ;Is it close?
754 jnz intch0 ;If not proceed.
755 contc: lxi d,infms9 ;Say we are back.
756 call prtstr
757 call syscls ; call system-dependent close routine
758 lda logflg ;Get the log flag.
759 ora a ;[pcc005] Check if open
760 cm logcls ;[pcc005] Close if needed
761 ret
762
763 ;Here if not a 'C' or '^C'
764
765 intch0: cpi 'S' ;Is it status?
766 jnz inch01 ;If not, proceed.
767 call stat01 ;Print out the status stuff.
768 call prcrlf ;[pcc011] add a crlf
769 jmp rskp ;return from conchr
770
771 inch01:
772 inch03: mov a,b ;Get the char.
773 cpi '?' ;Is it a help request?
774 jnz intch1 ;If not, go to the next check.
775 inch3a: lda logflg ;[pcc003] Logging flag
776 ora a ;[pcc003] see if active
777 jp inch04 ;[pcc005] jump if no file open
778 lxi d,loghlp ;[pcc003] yes, tell about R AND Q
779 call prtstr ;[pcc003]
780 inch04: lxi d,inthlp ;If so, get the address of the help message.
781 call prtstr
782 call sysinh ; print system-dependent help message
783 lxi d,inhlp1 ; Tell about doubling the escape character
784 call prtstr
785 call escpr ;Print escape character
786 lxi d,inhlp2 ;Print the rest
787 call prtstr
788 jmp intchr ;Get another char.
789
790 intch1: mov a,b ;Get the character.
791 cpi '0' ;Is it '0', to send a null?
792 jnz intch3 ;No.
793 xra a ;Yes, send an ASCII zero.
794 call setpar ; with the correct parity
795 mov e,a
796 call selmdm ; (to the modem...)
797 call outmdm
798 call selcon ; return with console selected
799 jmp rskp
800
801 intch3: lda escchr ;Get the escape char.
802 cmp b ;Is it the escape char?
803 jnz intch4 ;[pcc002] jump if not
804 mov a,b ;Get the char.
805 call setpar
806 mov e,a ;Restore it.
807 call selmdm
808 call outmdm ;Output it.
809 call selcon ;We promised console would be selected...
810 jmp rskp ;Return, we are done here.
811 intch4: mov a,b ;[pcc002] get it again
812 ani 137o ;[pcc002] in upper case
813 cpi 'P' ;[pcc002] toggle printer?
814 jnz intch5 ;[pcc003] nope
815 lda prnflg ;[pcc002] get printer flag
816 xri 01h ;[pcc002] complement it
817 sta prnflg ;[pcc002] and put back
818 jmp rskp ;[pcc002]
819 intch5: lda logflg ;[pcc003] get log flag
820 ora a ;[pcc003] See if open
821 jp intch7 ;[pcc003] no, skip R and Q
822 mov a,b ;[pcc003] get back chr
823 ani 137o ;[pcc003] make upper case
824 cpi 'R' ;[pcc003] Is it R
825 jnz intch6 ;[pcc003] Jump if not
826 mvi a,81H ;[pcc003] set flag for logging
827 sta logflg ;[pcc003] put it back
828 lxi d,inms28 ;[pcc003] message
829 call prtstr ;[pcc003]
830 jmp rskp ;[pcc003] done
831 intch6: cpi 'Q' ;[pcc003] Quit logging?
832 jnz intch7 ;[pcc003] no
833 mvi a,82H ;[pcc003] flag for open, but suspended
834 sta logflg ;[pcc003] store away
835 lxi d,inms27 ;[pcc003] keep them informed
836 call prtstr ;[pcc003]
837 jmp rskp ;[pcc003]
838 intch7: ;[pcc003]
839
840 intchz: mov a,b ; not recognized. get saved copy back.
841 push psw ;[8] save as we will want to test for 'D'
842 call sysint ; interpret system-dependent sequences
843 jmp intchy ; done. [10] Now see if D. If so, do a C.
844 pop psw ;[10] tidy stack
845 mvi e,'G'-100O ;Otherwise send a beep.
846 call outcon ; to the console.
847 jmp rskp
848
849 intchy: pop psw ;[10] adjust stack
850 ani 5fh ;[10] strip parity, make it upper case
851 cpi 'D' ;[10] was it a D?
852 jz contc ;[10] yup, so to the equivalent of an escape-C
853 jmp rskp
854 ;\f
855 ; Little code to allow some expansion of code without changing
856 ; every futher address, only up to the end of this file.
857 ; TO BE REMOVED FOR RELEASE!
858
859 ; org ($+100h) AND 0FF00H
860 IF lasm
861 LINK CPSCPM
862 ENDIF;lasm