.title K11PCO Connect code for PRO/350 Only .ident /347BDN/ .psect .enabl gbl ; Copyright (C) 1986 Brian Nelson ; ; This is a reformatting of the OLD K11CON.MAC cleaned up and ; specifically for the PRO/350 ONLY. Specific RSX TTDVR things ; have been removed. The old K11CON.MAC was getting to be such ; a mess that it becoming a pain to maintain. The CURRENT RSX ; connect code is K11MCO.MAC. ; ; ; 05-MAR-86 10:37 Brian Nelson Initial conversion ; 03-Apr-86 12:17 Brian Nelson Get XK read reposted before TT write ; 04-Apr-86 19:20 Brian Nelson Add support for spawning PRO/COMM .if ndf, K11INC .ift .include /IN:K11MAC.MAC/ .endc .psect concod ,RO,I,LCL,REL,CON .psect condat ,RW,D,LCL,REL,CON .mcall QIO$ QIOW$ QIOW$S DIR$ wtlo$s .mcall alun$s dscp$s encp$s exit$s rdaf$s srex$s .sbttl R/W Data .psect condat EF.REM = 14. ; Remote event flag EM.REM = 020000 ; Remote event flag mask EF.LOC = 15. ; Local event flag EM.LOC = 040000 ; Local event flag mask EF.LCW = 16. ; Local WRITE EF.RMW = 17. ; Remote WRITE ; Characteristics buffers savxk: .byte TC.BIN,0 ; XK/XT setting for BINARY mode .byte TC.8BC,0 ; XK/XT setting for EIGHT BIT xkspd: .byte TC.RSP,0 ; XK/XT receive speed .byte TC.XSP,0 ; XK/XT transmit speed sxklen = . - savxk ; Size for SF.GMC call savtt: .byte TC.FDX,0 ; TT1: setting for FULL DUPLEX .byte TC.NEC,0 ; TT1: for ECHOing .byte TC.BIN,0 ; TT1: setting for BINARY mode sttlen = . - savtt ; Size for SF.GMC call fdxchr: .byte TC.FDX,1 ; Always force FULL DUPLEX .byte TC.NEC,1 ; Always run without echoing .byte TC.8BC,1 ; Always set into eightbit mode .byte TC.BIN,1 ; /50/ Insure TC.BIN turned on .byte TC.BIN,0 ; No binary (maybe in the future) .byte TC.PTH,1 ; Pasthru (maybe in the future) ftisiz = .- fdxchr ; Size of settings for SF.SMC xkslen: .word ftisiz-4 ; Leave TC.BIN on, TC.PTH off for now ttslen: .word 4 ; Only FDX and NEC for TT1: xkpth:: .word 0 ; If GBLPAT'ted to <> 0, then turn ; off TC.BIN and turn on TC.PTH .sbttl More GMC and QIO definitions coming rtab: .byte TC.TBF,0 ; #chars in remote typeahead ltab: .byte TC.TBF,0 ; #chars in local typeahead ; Oft' used QIO DPB's remread: QIO$ ,lun.xk,ef.rem,,remios,, locread: QIO$ ,lun.co,ef.loc,,locios,, remwrite: QIOW$ io.wal,lun.xk,ef.rmw,,,, locwrite: QIOW$ io.wal,lun.co,ef.lcw,,,, locech: QIOW$ io.wal,lun.co,ef.lcw,,,, remtest: QIOW$ sf.gmc,lun.xk,ef.rem,,remios,, remtab: QIOW$ ,lun.xk,ef.rem,,remios,, efbuf: .blkw 4 ; Event flags buffer rembf: .blkb 257. ; Remote data buffer locbf: .blkb 4. ; Local data buffer .even eseen: .word 0 ; 1 = escape seen locios: .word 0,0 ; IO status blocks remios: .word 0,0 ; Ditto tempbf: .blkb 257. ; /50/ .even .mcall SPWN$S ,STSE$S ; /50/ If using PRO/COMM dtetask:.rad50 /DTE / ; /50/ Name of DTE dtests: .blkw 10 ; /50/ Spawn status SPEFN = 20 .psect concod ; End of R/W definitions .sbttl P/OS connect code .enabl lsb poscon::tst procom ; Should we use DTE today? beq 40$ ; No call getprv ; Do we need privs up? message ,CR message ,CR calls suspend ,<#2,#0> ; Wait a moment QIOW$S #IO.DET,#5 ; Detach terminal SPWN$S #dtetask,,,,,#SPEFN,,#dtests bcs 10$ ; See if the DTE spawn worked STSE$S #SPEFN ; It did, so we wait for DTE exit QIOW$S #IO.ATT,#5 ; Reattach terminal call drpprv ; Drop privs and exit return ; Back to caller ; 10$: movb @#$DSW ,r4 ; Save directive status message decout r4 ; Print the directive status message < Entering internal connect code.>,CR message ,CR br 45$ ; 40$: tst concnt ; bne 45$ ; message ; message ,CR message ,CR message ,CR message 45$: inc concnt ; message ; A message print #ttname ; XK0 or XTn message < Speed: > ; Inform about the speed also calls ttspeed ,<#ttname> ; Get the interface speed decout r0 ; Simple message ; A cr/lf message ,cr tst xkpth ; Should we set TC.PTH and turn beq 50$ ; off TC.BIN? If eq, then NO mov #FTISIZ,xkslen ; Yes, reset the SF.SMC size 50$: SREX$S #rsxabo ; Trap requested aborts clr eseen ; Insure no escapes already seen call getprv ; Insure privs for connect mode calls ttpars ,<#ttname> ; Get remote unit number ALUN$S #LUN.XK,r1,r0 ; Assign it ALUN$S #LUN.CO,#"TI,#0 ; Assign our local terminal QIOW$S #SF.GMC,#LUN.XK,#EF.REM,,,,<#savxk,#sxklen> QIOW$S #SF.GMC,#LUN.CO,#EF.LOC,,,,<#savtt,#sttlen> QIOW$S #SF.SMC,#LUN.XK,#EF.REM,,,,<#fdxchr,xkslen> QIOW$S #SF.SMC,#LUN.CO,#EF.LOC,,,,<#fdxchr,ttslen> QIOW$S #IO.DEL,#LUN.CO QIOW$S #IO.ATA,#LUN.CO,,,,,<,#0,#conast> .sbttl RSX Connect code - Remote Input ; Prime incoming and outgoing streams DIR$ #remread DIR$ #locread ; Main loop - Handle incoming and outgoing streams ; until escape character is detected on outgoing (local KB) 60$: WTLO$S 0,# ; Wait for a character on either RDAF$S #efbuf ; Read the event flags movb remios ,r5 ; Get the status of the read call iocheck ; Insure that it worked bcs 100$ ; No good, DIE call xkin ; Check for XK driver input bcs 100$ ; Something went wrong call ttin ; Check for TT1 input bcc 60$ ; Next if all was well 100$: call rsxrst ; Restore terminal settings call setcc ; Insure control C trap is correct call drpprv ; Drop privs return .dsabl lsb ; Please rsxabo: call rsxrst ; called via requested exit SREX$S ; disable further exits EXIT$S ; bye rsxrst: SREX$S ; Don't keep reentering QIOW$S #IO.KIL,#LUN.XK,#EF.REM ; Kill incoming I/O QIOW$S #IO.KIL,#LUN.CO,#EF.LOC ; Kill incoming I/O QIOW$S #SF.SMC,#LUN.XK,#EF.REM,,,,<#savxk,#sxklen> QIOW$S #SF.SMC,#LUN.CO,#EF.LOC,,,,<#savtt,#sttlen> QIOW$S #IO.DET,#LUN.XK,#EF.REM ; De-Attach remote line return .sbttl Process input from the XK/XT port ; We do a rather odd thing here to improve the interactive ; response of the console terminal at high XK port speeds. It ; turns out the the XK driver can buffer so much data that at ; high speeds we may NEVER be able to get a control C out ; from the console through the XK port. Thus at high speeds ; we do EXACTLY what one would not normally do, that it we ; CUT the read sizes down in order to give the TTDVR a chance ; to read TT1: input and get it out the XK port via that ; driver. We won;t loose data, the XK driver is very good ; about buffering and flow control. Of course, another ; possibility would be to place the TI: read at a higher ; priority. xkin: bit #em.rem,efbuf+0 ; Anything coming in? beq 100$ ; (no) ; DIR$ #remtest ; More in typeahead? clr r0 ; XK may have a lot ready to get bisb rtab+1,r0 ; R0 = number of chars in typeahead beq 20$ ; Nothing at all in typeahead cmpb xkspd+1,#S.2400 ; Are we going fast today? blos 10$ ; No cmp r0 ,#40 ; Yes, should we drop size of read? blos 10$ ; No, we expect that control C's mov #40 ,r0 ; can make it out. Otherwise drop it 10$: mov r0,remtab+q.iopl+2 ; Set the number to read to drain DIR$ #remtab ; Read whats sitting around ; 20$: inc r0 ; R0 = total number of chars to show clrb rembf(r0) ; Make it .asciz for mapping code mov r0 ,-(sp) ; No, clear out the high bit mov #rembf ,r1 ; For the entire buffer mov #tempbf ,r4 ; /50/ Make a copy of the buffer 30$: movb (r1)+ ,(r4) ; /50/ Copy the data tst con8bit ; /50/ Clear the high bit off? bne 40$ ; /50/ No, leave as is bicb #200 ,(r4) ; /50/ Simple to do 40$: inc r4 ; /50/ dst++ sob r0 ,30$ ; Next please mov (sp)+ ,r0 ; Restore the byte count now ; mov r0 ,locwri+q.iopl+2; Write out this many mov #tempbf ,r2 ; /50/ We moved the data around a bit mov r2 ,locwri+q.iopl+0; /50/ Reset corrected buffer address DIR$ #remread ; /50/ Re-issue read ; 50$: movb (r2) ,r1 ; Now dump to the logging file call dumplo ; If logging is currently enabled cmpb (r2) ,#'S&37 ; /48/ Xoffs are not to be suffered bne 60$ ; /48/ Not an XOFF clrb (r2) ; /48/ Xoff, convert it to a NULL 60$: inc r2 ; /48/ Next character please sob r0 ,50$ ; Next CH please DIR$ #locwrite ; Normal writes 100$: clc ; Success always return ; Exit .sbttl Check for input from TT1: ttin: mov #cvtbuf ,cvtadr ; For converting pro/350 codes clrb cvtbuf ; Nothing is there for now clrb cvtbuf+1 ; Ditto... bit #em.loc,efbuf+0 ; Anything typed locally? beq 100$ ; No, just exit clr r1 ; Pass 8bit ctls for pro/350 bisb locbf ,r1 ; R1 = just typed character call proesc ; Is this a pro/350 ESC or BS? bcs 10$ ; No movb @cvtadr ,locbf ; And setup send for first char movb @cvtadr ,r1 ; Ditto beq 80$ ; Nothing to do inc cvtadr ; Point to the next character 10$: bic #^C177 ,r1 ; Drop bit 7 if mark set (BDN) cmpb r1 ,conesc ; Console escape? bne 20$ ; (no) tst eseen ; Already seen one escape? bne 30$ ; (yes, send this one) inc eseen ; Yes, note it for now br 40$ ; And go read again 20$: tst eseen ; Character following conesc? beq 30$ ; (no, send it) call concmd ; Yup, process it clr eseen ; Clear the flag tst r0 ; Exit CONNECT mode? bgt 110$ ; Yes, clean up etc blt 40$ ; no, but it was a command 30$: clr eseen ; Clear the flag setpar locbf ,locbf ; Set correct outgoing parity DIR$ #remwrite ; Transmit character to remote tst duplex ; IBM type things today? beq 40$ ; No DIR$ #locech ; Need half duplex duplex ? 40$: movb @cvtadr ,locbf ; Anymore conversion chars to beq 80$ ; To transfer over? inc cvtadr ; No, get the next one please br 30$ ; Next please 80$: DIR$ #locread ; Re-issue local read mov #cvtbuf ,cvtadr ; Reset conversion address clrb @cvtadr ; Insure .asciz 100$: clc ; Success return ; Exit 110$: sec ; Failure or EXIT CONNECT return .sbttl map pro/350 codes to vt100 codes .dsabl lsb ; Following code added edit 2.39 /39/ ; ; ; The following code, to (1) intercept 'DECID' and return a ; VT100 term type instead of P/OS's mess that few execs ; recognize, and (2) to map some of the upper row LK201 Pro/350 ; function keys into useable characters were made at the request ; of Bernie Eiben of DEC LDP (eiben@dec-marlboro.arpa, ; eiben%lsmvax.dec@decwrl.arpa). Currently, the mapping is as ; follows (as of 18-NOV-1985 14:08) ; ; F5 (break) --> send a 'real' break ala IO.BRK for XKdriver ; F6 (interupt) --> send \03 (control C) ; F10 (exit) --> send \032 (control Z) ; F11 (ESC) --> send \033 (esc) ; F12 (BS) --> send \010 (backspace) ; ; Since these settings may intfere with some editor functions keys ; they can be disabled via the SET TER VT200 command. The mapping ; of F11 is notable to TOPS20 users for command completion. In my ; opinion, the mods were well worth it, though mapping F10 to \032 ; does present some difficulties. A future version of this code ; would most likely access a global data structure to map settable ; codes (with defaults) to specified character sequences. Ie, we ; may end up rewritting PRO/COMM functionality for Kermit-11/POS. .save .psect mapdata ,rw,d,lcl,rel,con ; In the list specified in MAPSEQ, the translation of P/OS ; escape sequences from the upper row function keys is normally ; an ascii character string. The exceptions are (1) if the first ; character is a \0377 then the next character is assumed to be ; the argument of a connect mode 'escape' command, such as ^\B ; for sending a break, or perhaps a possible mapping of F8 (or ; F7) (\033[19\0176 and \033[18\0176) to a ^\C command. The ; mapping or a sequence to a NULL tells the mainline emulator ; code to do nothing (a NOP). INSEQ is simply the P/OS generated ; ecsape sequences. mapseq: .word 10$,20$,30$,40$,50$,60$,70$,80$,90$ .word 100$,110$,120$ .word 0 10$: .byte 10,0 ; return for F10 20$: .byte 33,0 ; return for F11 30$: .byte 3,0 ; return for F6 40$: .byte 'Z&37,0 ; return for F10 50$: .byte 377,'b,0 ; fake ^\b break cmd 60$: .asciz <33>/[?1;0c/ ; vt101 response 70$: .asciz <33>/[?1;0c/ ; vt101 response 80$: .asciz <33>/[?1;0c/ ; vt101 response 90$: .asciz <33>/[?1;0c/ ; vt101 response 100$: .asciz <33>/[?1;0c/ ; vt101 response 110$: .asciz <33>/[?1;0c/ ; vt101 response 120$: .asciz <33>/[?1;0c/ ; vt101 response .even inseq: .word 10$,20$,30$,40$,50$,60$,70$,80$,90$ .word 100$,110$,120$ .word 0 10$: .byte '2,'4,176,0 ; generated code for BS (10) 20$: .byte '2,'3,176,0 ; generated code for ESC (33) 30$: .byte '1,'7,176,0 ; generated code for INT (3) 40$: .byte '2,'1,176,0 ; exit key 50$: .byte '1,'5,176,0 ; break 60$: .asciz /?21;0;0;/ ; part of response to DECID 70$: .asciz /?21;1;0;/ ; part of response to DECID 80$: .asciz /?21;2;0;/ ; part of response to DECID 90$: .asciz /?21;0;0;8;0c/ ; baseline p/os 2.0 system 100$: .asciz /?21;1;0;8;0c/ ; baseline p/os 2.0 system 110$: .asciz /?21;2;0;8;0c/ ; baseline p/os 2.0 system 120$: .asciz /?21;3;0;8;0c/ ; baseline p/os 2.0 system .even inid: .word 10$,40$ ; host strings to return ID .word 0 ; DECID is 'not recommended' 10$: .byte 33,'Z&137,0 ; but intil 52's are gone... 40$: .byte 33,'Z&137,15,0 ; just in case .even outid: .asciz <33>/[?1;0c/ ; vt101 response .even iosb: .word 0,0 ; a QIOW$S i/o status block smallb: .word 0 ; a QIOW$S buffer cvtbuf: .blkb 30 ; copy translated codes to cvtadr: .word cvtbuf ; a pointer to it .even .restore .sbttl DECID and PRO esc seq conversion code, continued... .mcall mrkt$s ,cmkt$s ,astx$s ,wtse$s mapid: save ; save register please tst proflg ; really on a pro/350? beq 100$ ; no cmpb vttype ,#VT100 ; iif we think we are a vt100 bne 100$ ; no cmpb @r2 ,#33 ; ESC ? bne 100$ ; no 5$: strlen r2 ; is there enough to look for? dec r0 ; well ? bne 20$ ; yes, go ahead with checks mrkt$s #20,#12,#1,#200$ ; time the read to be very short QIOW$S #IO.RAL!TF.RNE,#LUN.XK,,,#iosb,,<#smallb,#1> cmkt$s #20,#200$ ; kill the timed read cmpb iosb ,#IS.SUC ; successfull read? bne 100$ ; no, exit on error inc locwrite+q.iopl+2 ; fix i/o count up movb smallb ,1(r2) ; yes, append the character now clrb 2(r2) ; insure asciz 20$: clr r3 ; yes 30$: tst inid(r3) ; done looking ? beq 100$ ; yes strcmp r2 ,inid(r3) ; check tst r0 ; found it? bne 40$ ; no strlen #outid ; yes QIOW$S #IO.WAL,#LUN.XK,,,,,<#outid,r0> br 90$ ; exit 40$: tst (r3)+ ; not found, check again br 30$ ; next 90$: sec ; say we sent a response br 110$ ; exit 100$: clc ; say we never sent response 110$: unsave ; exit return ; bye 200$: QIOW$S #IO.KIL,#LUN.XK ; abort the qio if timeout astx$s ; exit marktime ast .sbttl Map keyboard codes to something reasonable proesc: save ; save a register please cmpb vttype ,#VT100 ; not is we really want pro bne 90$ ; exit mov #cvtbuf ,r4 ; get address of conversion buf clrb @r4 ; assume failure cmpb r1 ,#233 ; escape character typed 8bit? beq 10$ ; yes cmpb r1 ,#33 ; escape w/o bit 7 set bne 90$ ; no, exit with C set 10$: mrkt$s #20,#2,#1 ; insure we wait long enough wtse$s #20 ; to get all the data input QIOW$S #SF.GMC,#LUN.CO,,,,,<#ltab,#2> ;/ 39/ yes, get typeahead count movb ltab+1 ,r2 ; check for typeahead count beq 90$ ; nothing to do QIOW$S #IO.RAL!TF.RNE,#LUN.CO,,,,, clrb cvtbuf(r2) ; insure .asciz mov r4 ,r3 ; get address of data read cmpb @r3 ,#'[ ; esc [ or CSI ? bne 15$ ; must be CSI inc r3 ; must be ESC [ 15$: clr r2 ; look for a matching esc seq 20$: tst inseq(r2) ; all done beq 90$ ; exit with C set strcmp r3 ,inseq(r2) ; did we get a pro/350 esc seq? tst r0 ; ... bne 30$ ; no mov mapseq(r2),r3 ; yes, get the translation cmpb @r3 ,#377 ; fake emulator command? bne 25$ ; no inc eseen ; say we have a ctrl\ movb 1(r3) ,(r4)+ ; yes, return 1 char code clrb (r4)+ ; insure .asciz br 100$ ; exit success 25$: strcpy r4 ,r3 ; yes, copy the mapped string br 100$ ; and exit 30$: add #2 ,r2 ; not done, next please br 20$ ; 90$: sec ; failure br 110$ ; exit 100$: clc ; success 110$: unsave ; pop regs and exit return conast: QIOW$S #IO.WAL,#LUN.XK,,,,,<#cc,#1> tst (sp)+ astx$s .save .psect condat cc: .byte 3,0 .restore .sbttl check for allowable i/ o errors for RSX/ M+ and P/ OS iocheck:mov r0 ,-(sp) ; insure this is saved tstb r5 ; sucessesful read qio ? bpl 180$ ; yes scan r5 ,#errs ; allowable error code ? tst r0 ; well bne 180$ ; yes, let it through neg r5 ; make > 0 for direrr macro direrr r5 ; simple sec ; failure, exit to command level br 190$ ; bye 180$: clc ; success, stay in connect code 190$: mov (sp)+ ,r0 ; restore old r0 please return .save .psect condat errs: .byte IE.BCC ,IE.DAO ,IE.IES ,IE.NOD ,IE.PES ,IE.VER ,IE.ABO ,0 .even .restore global .dsabl lsb .sbttl concmd terminal emulation escape commands .enabl lsb concmd: save bicb #^C177 ,r1 scan r1,#200$ ; look for a match here tst r0 ; if no match, return 0 beq 100$ ; ok asl r0 ; word offsets jsr pc ,@210$(r0) ; dispatch to the correct routine tst r0 ; if not set then set to -1 bne 100$ ; already set dec r0 ; set to -1 100$: unsave ; pop r1 and exit return .save .psect condat 200$: .byte 'C&137 ,'c!40 ; drop connection ctrl \ C .byte 'I&137 ,'i!40 ; init the line .byte 'Q&137 ,'q!40 ; quit logging but leave file open .byte 'R&137 ,'r!40 ; resume logging if file is open .byte 'X&137 ,'X!40 ; control Q and then thats all .byte 'B&137 ,'b!40 .byte '? ,177 ; help, rub for send break .byte 'H&137 ,'h!40 .byte 0 .even 210$: .word con.$ ; unknown escape command .word con.c ,con.c ; drop connection .word con.i ,con.i ; get modems attention .word con.q ,con.q ; turn console logging off .word con.r ,con.r ; turn it back on please .word con.x ,con.x ; send XON .word con.br ,con.br ; break .word con.hl ,con.br ; print out commands .word con.hl ,con.hl ; help .beep: .byte 'G&37 .xon: .byte 'Q&37,0 .even .restore .dsabl lsb con.$: calls binwri ,<#.beep,#1,#lun.co> ; beep at user clr r0 return con.c: mov #1 ,r0 ; set flag to exit connect code return ; simple con.i: calls ttydtr ,<#ttname> ; try to force DTR up on the line clr r0 return con.q: bic #log$co ,trace ; turn off console logging clr r0 return con.r: bit #log$op ,trace ; if the file is open do it beq 100$ ; no bis #log$co ,trace ; yes, enable this 100$: clr r0 return con.x: QIOW$S #IO.WAL,#LUN.XK,,,,,<#.xon,#1> calls ttxon ,<#ttname> clr r0 return con.br: QIOW$S #IO.KIL,#LUN.XK ; Abort the read qio QIOW$S #IO.BRK,#LUN.XK,,,,,<#0>; Get XK driver to do it DIR$ #remread ; Re-prime the read clr r0 ; Success return .enabl lsb con.hl: strlen #200$ calls binwri ,<#200$,r0,#lun.co> clr r0 return .save .psect condat 200$: .ascii /B Try to send a break to the remote/ .ascii /C Connect back to the local Kermit-11/ .ascii /I Drop and raise DTR (for RSTS only)/ .ascii /Q Quit console logging. See SET LOG/ .ascii /R Resume console logging. See SET LOG/ .ascii /X Send XON and cancel any active XONs/ .asciz /RUBOUT Try to fake a break to the remote/ .ascii /? Print this message/ .byte 0 .even .restore .dsabl lsb .sbttl dump i/o to a log file ? dumplo: bit #log$co ,trace ; is this enabled ? beq 100$ ; no bit #log$op ,trace ; is it open beq 100$ ; no save ; yes, save temps please mov r1 ,r0 ; call simple version mov #lun.lo ,r1 ; unit number call putcr0 ; thats it folks unsave 100$: return sxon: tst conflow beq 100$ QIOW$S #IO.WAL,#LUN.XK,,,,,<#xon,#1> 100$: return sxoff: tst conflow beq 100$ QIOW$S #IO.WAL,#LUN.XK,,,,,<#xoff,#1> 100$: return .save .psect $pdata xon: .byte 'Q&37 xoff: .byte 'S&37 .even .restore global .end