.sbttl K11ECO New RSTS/E connect code .psect .ident /2.50.1/ .include /SY:[1,2]COMMON.MAC/ .if ndf, K11INC .ift .include /IN:K11MAC.MAC/ .endc .enabl gbl ; Copyright (C) 1986 Change Software, Inc ; ; 02-Apr-86 14:58:29 Brian Nelson ; ; Warning: This uses binary I/O, thus you never want to ; ; (1) Do I/O to channel zero ; (2) Timeout on a terminal read ; ; Either one of the above events will cause binary mode ; to go away. We can't use multiple delimiters here due ; to the terminal drivers processing of C1 controls. ; ; This is tested only on RSTS/E 9.1 and Field Test 9.2 ; It should work fine on 8.0-07, but no gaurentees. .psect concod ,ro,i,lcl,rel,con .psect condat ,rw,d,lcl,rel,con .macro READTT buffer,size=#80.,lun,time=#0 mov time ,-(sp) mov lun ,-(sp) mov size ,-(sp) mov buffer ,-(sp) call $READTT .endm READTT .macro WRITETT buffer,size=#0,lun mov lun ,-(sp) mov size ,-(sp) mov buffer ,-(sp) call $WRITETT .endm WRITETT .macro fqcopy dst ,src mov src ,-(sp) mov dst ,-(sp) call $fqcopy .endm fqcopy .macro CLRFQB call $clrfq .globl $clrfq .endm CLRFQB .macro CLRXRB call $clrxr .globl $clrxr .endm CLRXRB NODATA == 13. ; no data for terminal read DETKEY == 27. ; i/o to detached tt line .psect condat .even xksdon: .blkw 1 ; Remote terminal set done ttsdon: .blkw 1 ; Local terminal set done ioseen: .blkw 1 ; Some input was seen somewhere ttio: .blkw 1 ; Console read worked xkio: .blkw 1 ; Remote read worked eseen: .blkw 1 ; Control \ happened at console savtt: .blkb 40 ; Save local terminal chars savxk: .blkb 40 ; Save outgoing line chars bufqxk: .blkw 1 ; Connect line buffer quota ttunit: .blkw 1 ; Our console terminal unit xkunit: .blkw 1 ; Connected line's unit number v9flag: .blkw 1 ; Iff version 9.x or later XKSIZE = 600 ; Large buffers for remote reads xkbuff: .blkb XKSIZE+2 ; Buffer for connected line ttbuff: .blkb 80. ; Buffer for console terminal .psect concod .enabl lsb doconn::call init ; Startup bcs 100$ ; Oops call ttinit ; Save terminal characteristics bcs 90$ ; Die ; 10$: mov #ttbuff ,r4 ; Pointer to local term buffer mov #xkbuff ,r5 ; Pointer to remotes buffers. READTT buffer=r4,lun=#LUN.CO,size=#1 ; Look for data on LOCAL term tst r0 ; Was there anything there? bne 50$ ; No ; mov sp ,ioseen ; Yes, flag that we saw some I/O movb @r4 ,r0 ; Check for console commands bicb #^C177 ,r0 ; Insure no parity set. cmpb r0 ,conesc ; Escape command prefix ? bne 20$ ; No READTT buffer=r4,lun=#LUN.CO,size=#1,time=#20 tst r0 ; Successfull bne 50$ ; No, ignore the data movb @r4 ,r0 ; Check for console commands bicb #^C177 ,r0 ; Insure no parity set. cmpb r0 ,conesc ; Escape command prefix ? beq 20$ ; Yes, dump the character now. call concmd ; Check for console command. br 80$ ; And skip the next remote read 20$: tst duplex ; Is this a half duplex line? beq 25$ ; No, then don't echo the data WRITETT buffer=r4,lun=#LUN.CO,size=#1 25$: mov r4 ,r2 ; Insure parity is setup now. mov r1 ,r3 ; The byte count next beq 50$ ; Nothing there ? 30$: setpar @r2 ,(r2)+ ; Set parity if need be. sob r3 ,30$ ; Next character please. WRITETT buffer=r4,lun=#LUN.XK,size=#1 50$: READTT buffer=r5,lun=#LUN.XK,size=#XKSIZE tst r0 ; Did the remote read succeed? beq 60$ ; Yes, dump to local terminal. call iocheck ; No, check for allowable errors br 80$ ; And exit with C set for FATAL 60$: mov sp ,ioseen ; Had some input, flag no SLEEP mov r5 ,-(sp) ; Now get rid of XOFF characters mov r1 ,r0 ; Save buffer address and byte count beq 75$ ; Be SURE that byte count is nonzero. 65$: cmpb (r5) ,#'S&37 ; If this is an off then replace it bne 66$ ; will a NULL character please. clrb (r5) ; Was an XOFF, so stuff a NULL in. 66$: cmpb parity ,#PAR$NONE ; Parity up? beq 70$ ; No bicb #200 ,(r5) ; Yes, dump it 70$: inc r5 ; Next please sob r0 ,65$ ; Keep going 75$: mov (sp)+ ,r5 ; Restore the buffer pointer. WRITETT buffer=r5,lun=#LUN.CO,size=r1 call dumplog ; May need to dump to log file clc ; Success flag 80$: bcs 90$ ; If set, it's time to EXIT tst ioseen ; Not set, do we really want to bne 85$ ; take a short nap ? If ne, no. CLRXRB ; Yes, insure future rsts/e's ok mov #1 ,XRB+0 ; One second sleep .SLEEP ; Do it 85$: clr ioseen ; No more i/o has been seen br 10$ ; Next please 90$: call ttrst ; Restore terminal chars 100$: return .dsabl lsb .sbttl misc support routines .enabl lsb init: clr eseen ; No escape seen clr xkio ; No remote I/O seen clr ttio ; No local I/O seen clr ioseen ; No I/O at all happened clr ttsdon ; No terminal settings done yet clr xksdon ; No terminal settings done yet CLRFQB ; Zap the firqb please movb #UU.PRV ,FIRQB+FQFUN ; Execute a V9 only call so we .UUO ; can see if this is still v8 clr v9flag ; Assume v8 tstb FIRQB ; Did this call succeed? bne 10$ ; No mov sp ,v9flag ; Yes, this is 9.0 or later 10$: tstb ttname ; Any line previously defined? bne 30$ ; Yes tstb @argbuf ; Any name on the command line? bne 20$ ; Yes MESSAGE ,cr jmp 90$ ; Error exit 20$: strcpy #ttname ,argbuf ; No name, copy from command line 30$: CLRFQB ; Get our console terminal unit # movb #UU.SYS ,FIRQB+FQFUN ; Do the systat call now .UUO ; Simple movb FIRQB+5 ,ttunit ; Save our terminal unit number mov #XRB ,r3 ; Get the unit number next mov #ttname ,r2 ; Load up the XRB CLRFQB ; Insure no odd defaults around CLRXRB ; Ditto STRLEN r2 ; Get the length of the device name mov r0 ,(r3)+ ; Copy the length of the name mov r0 ,(r3)+ ; ...Copy the length of the name mov r2 ,(r3)+ ; Copy the device name address .FSS ; Do a filename string scan now movb FIRQB ,r0 ; Successfull? bne 80$ ; No, exit movb FIRQB+FQDEVN,xkunit ; Save the connected line unit# bit #20000!40000,XRB+10 ; Did we REALLY get a devicename? bne 40$ ; Yes movb #6 ,r0 ; No, preload bad device name br 80$ ; And exit with error MESSAGE 40$: cmpb xkunit ,ttunit ; Are they one and the same ? bne 50$ ; No, it's ok MESSAGE ,cr br 90$ ; Error if so 50$: tst doallo ; /58/ Really assign it? beq 55$ ; /58/ No CLRFQB ; Insure outgoing line is assigned movb #UU.ASS ,FIRQB+FQFUN ; Subfunction code mov #"KB ,FIRQB+FQDEV ; KB movb xkunit ,FIRQB+FQDEVN+0 ; Unit number movb #377 ,FIRQB+FQDEVN+1 ; Unit number is real .UUO ; Simple 55$: CALLS ttspeed ,<#ttname> ; Get interface speed mov r0 ,r2 ; Save the speed MESSAGE ; Dump the data print #ttname ; And the connect line name tst r2 ; Any speed info available? beq 60$ ; No MESSAGE < Speed: > ; Yes, dump the speed decout r2 ; Simple MESSAGE ; A crlf MESSAGE ; How to return to the local kermit clr -(sp) ; .... bisb conesc ,(sp) ; The current control escape char. add #100 ,(sp) ; Convert to printable representation mov sp ,r0 ; ..... print r0 ; ..... MESSAGE ,cr ; All done. tst (sp)+ ; Pop this 60$: MESSAGE ; A final CR/LF ; 70$: clc ; Success br 100$ ; Exit 80$: direrr r0 ; Print RSTS/E error text 90$: sec ; Failure 100$: return ; Exit .dsabl lsb .sbttl save/set/restore terminal characteristics .enabl lsb ttinit: movb #377 ,r0 ; Console terminal first call 200$ ; Get term chars, part 0 FQCOPY #savtt+0,#FIRQB ; Save the characteristics movb xkunit ,r0 ; Now for the CONNECTED terminal call 200$ ; Ditto... FQCOPY #savxk+0,#FIRQB ; Copy this also tst v9flag ; Will the second part of the beq 10$ ; get terminal chars succeed? clrb bufqxk ; Clear buffer quota outz CLRFQB ; Yes, read the buffer quota movb #UU.TRM ,FIRQB+FQFUN ; Again ... incb FIRQB+4 ; Subfunction = 1 movb xkunit ,FIRQB+5 ; Unit number of connected line .UUO ; Read current buffer quota tstb FIRQB ; Success? bne 10$ ; No, ignore it movb FIRQB+27,bufqxk ; Save it CLRFQB ; Clear again movb #UU.TRM ,FIRQB+FQFUN ; .... incb FIRQB+4 ; Subfunction = 1 movb xkunit ,FIRQB+5 ; Unit number ..CBFQ == . + 2 ; movb #/40,FIRQB+27 ; Buffer twice our internal size .UUO ; Do it ... 10$: movb #377 ,r0 ; Now set chars at last mov #LUN.CO ,r1 ; Channel number for open call 210$ ; ..... bcs 110$ ; It failed? inc ttsdon ; Set and open done for local term movb xkunit ,r0 ; Again please mov #LUN.XK ,r1 ; Channel number for open call 210$ ; ..... bcs 110$ ; Save success flag inc xksdon ; Set and open done for remote term 100$: clc ; Say success and exit 110$: return ; At last 200$: CLRFQB ; Insure FIRQB is cleared out movb #UU.TRM ,FIRQB+FQFUN ; Terminal call today. movb r0 ,FIRQB+5 ; Console terminal this time .UUO ; Simple clrb FIRQB+4 ; Insure this field is (v8/v9) bisb FIRQB+36,FIRQB+20 ; Get 8bit setting in correct loc. clr FIRQB+36 ; And clear this field out return ; Exit 210$: CLRFQB ; Clear FIRQB again.... movb #UU.TRM ,FIRQB+FQFUN ; Terminal call today. movb r0 ,FIRQB+5 ; Console terminal this time movb #377 ,FIRQB+12 ; XON movb #377 ,FIRQB+35 ; GAG movb #31 ,FIRQB+20 ; 8bit and NoParity movb #200 ,FIRQB+11 ; LC output movb #377 ,FIRQB+15 ; LC input movb #377 ,FIRQB+23 ; No Uparrow movb #200 ,FIRQB+30 ; No delimiters please .UUO ; Simple cmpb r0 ,#377 ; Console terminal? bne 215$ ; No movb ttunit ,r0 ; Yes, insure valid unit number ; 215$: CLRXRB ; Clear the XRB mov #3 ,XRB+0 ; Function (disable echoing) mov r0 ,XRB+2 ; Terminal number movb #TTYHND ,XRB+7 ; The device driver index next .SPEC ; Do it. ; CLRFQB ; Now open the terminal up movb #OPNFQ ,FIRQB+FQFUN ; Function code movb r1 ,FIRQB+FQFIL ; Channel number aslb FIRQB+FQFIL ; Times two, of course. mov #100001 ,FIRQB+FQMODE ; Binary mode mov #"KB ,FIRQB+FQDEV ; Device type movb r0 ,FIRQB+FQDEVN+0 ; Unit movb #377 ,FIRQB+FQDEVN+1 ; It's for real CALFIP ; Open it up and exit movb FIRQB ,r0 ; Did the open succeed? beq 220$ ; Yes MESSAGE direrr r0 ; No, an error MESSAGE please sec ; Exit return ; Bye 220$: clc ; Success return ; Exit .dsabl lsb .sbttl restore terminals .iif ndf, TTYHND, TTYHND = 2 ttrst: CLRFQB ; Close channels up please movb #CLSFQ ,FIRQB+FQFUN ; Close a channel function movb #LUN.XK*2,FIRQB+FQFIL ; Channel number times 2 CALFIP ; Simple CLRFQB ; Insure FIRQB is clear again movb #CLSFQ ,FIRQB+FQFUN ; Close a channel function movb #LUN.CO*2,FIRQB+FQFIL ; Channel number times 2 CALFIP ; Simple CLRXRB ; Reset echoing on console term mov #2 ,XRB+0 ; Function (enable echoing) mov ttunit ,XRB+2 ; Terminal number movb #TTYHND ,XRB+7 ; The device driver index next .SPEC ; Do it. tst ttsdon ; Did we ever set this? beq 10$ ; No FQCOPY #FIRQB ,#savtt+0 ; Restore console terminal movb #UU.TRM ,FIRQB+FQFUN ; Function code clrb FIRQB+4 ; Insure cleared for v9..x movb #377 ,FIRQB+5 ; Console .UUO ; Simple 10$: tst xksdon ; Did we set the remote up? beq 100$ ; No FQCOPY #FIRQB ,#savxk+0 ; Restore connected terminal movb #UU.TRM ,FIRQB+FQFUN ; Function code clrb FIRQB+4 ; Insure cleared for v9..x movb xkunit ,FIRQB+5 ; Console .UUO ; Simple tst v9flag ; Version 9 or later? beq 100$ ; No CLRFQB ; Yes, restore buffer quota movb #UU.TRM ,FIRQB+FQFUN ; Function incb FIRQB+4 ; Subfunction = 1 movb xkunit ,FIRQB+5 ; Unit number movb bufqxk ,FIRQB+27 ; Stuff saved buffer quota .UUO ; Do it 100$: clc ; Say it worked and exit return ; Bye .sbttl read/write terminals $READTT:mov #XRB ,r0 ; Point to the XRB please tst 10(sp) ; No wait desired today? beq 10$ ; Yes (the normal case) mov 10(sp) ,(r0) ; No, SLEEP instead of TIMEOUT .SLEEP ; Sleep until tmo or something 10$: mov 4(sp) ,(r0)+ ; is typed. Stuff a buffer size bne 20$ ; Make sure the buffer size is ok inc -2(r0) ; Not ok, make it one character 20$: clr (r0)+ ; Clear returned byte count mov 2(sp) ,(r0)+ ; Buffer address movb 6(sp) ,(r0) ; Channel number aslb (r0)+ ; Times two clrb (r0)+ ; Unused (byte) clr (r0)+ ; Unused (word) clr (r0)+ ; No timeouts with binary mode mov #8192. ,(r0)+ ; No stalling please .READ ; Do it clr r1 ; Assume no data movb FIRQB ,r0 ; Success? bne 100$ ; No mov XRB+XRBC,r1 ; Yes, return byte count 100$: mov (sp) ,10(sp) ; Move return address up add #4*2 ,sp ; Pop parameters and exit return ; Bye $writet:mov r1 ,-(sp) ; Save it mov 4+2(sp) ,r0 ; Size of the write bne 10$ ; It's ok mov 2+2(sp) ,r1 ; No, get the asciz size now strlen r1 ; .... 10$: mov #XRB ,r1 ; Point to XRB please mov r0 ,(r1)+ ; Byte count mov r0 ,(r1)+ ; Byte count again mov 2+2(sp) ,(r1)+ ; Buffer address movb 6+2(sp) ,(r1) ; Channel number aslb (r1)+ ; Times two clrb (r1)+ ; Unused (byte) clr (r1)+ ; Unused (word) clr (r1)+ ; Unused (word) again mov #4096. ,(r1)+ ; IO.WAL .WRITE ; Do it mov (sp)+ ,r1 ; Restore this one mov (sp) ,6(sp) ; Move return address up add #3*2 ,sp ; Ignore parameters return $fqcopy:save ; Copy a block of data mov 2+6(sp) ,r2 ; Destination mov 4+6(sp) ,r1 ; Source mov #40 ,r0 ; Size of a FIRQB 10$: movb (r1)+ ,(r2)+ ; Copy a byte sob r0 ,10$ ; Next please unsave ; Pop registers mov (sp) ,4(sp) ; Move return address cmp (sp)+ ,(sp)+ ; Pop stack return ; Exit .enabl lsb iocheck:cmpb r0 ,#DETKEY ; I/O to detached Keyboard? beq 80$ ; Yes, it's fatal cmpb r0 ,#NODATA ; Simply no data present? beq 70$ ; Yes, that one is ok movb #ERRFQ ,FIRQB+FQFUN ; Dump error text out next movb r0 ,FIRQB+4 ; Pass the error code also CALFIP ; Simple to do clrb FIRQB+37 ; Insure .asciz WRITETT buffer=#FIRQB+4,lun=#LUN.CO WRITETT buffer=#220$,lun=#LUN.CO; A finishing CRLF 70$: clc ; Not fatal return ; Exit 80$: WRITETT buffer=#210$,lun=#LUN.CO; Dump an error MESSAGE please sec ; This is FATAL return ; Bye .save .psect rwdata ,d,lcl,rel,con,rw 200$: .asciz /%Read error - / 210$: .asciz /??DETKEY error - DTR not present or has been lost/ 220$: .byte CR,LF,0 .even .restore .dsabl lsb .sbttl concmd terminal emulation escape commands .enabl lsb concmd::mov r1 ,-(sp) ; Save it movb @r4 ,r1 ; Get the character to check bicb #^C177 ,r1 ; Must drop parity scan r1 ,#200$ ; look for a match here asl r0 ; word offsets jsr pc ,@210$(r0) ; dispatch to the correct routine 100$: mov (sp)+ ,r1 ; Pop R1 and exit return .save .psect rwdata ,rw,d,lcl,rel,con 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 .restore ; Pop code psect context .dsabl lsb ; Turn off current symbol block con.$: WRITETT buffer=#$bel,lun=#LUN.CO; Send a beep out for unknown clc ; commands. Say it is not fatal. return ; Bye con.c: sec ; Exit connection return ; And return con.i: CALLS ttydtr ,<#ttname> ; try to force DTR up on the line clc ; And say it's NOT fatal return ; Exit con.q: bic #log$co ,trace ; turn off console logging clc ; Successfull return ; Exit con.r: bit #log$op ,trace ; if the file is open do it beq 100$ ; no bis #log$co ,trace ; yes, enable this 100$: clc ; Success return ; Exit con.x: WRITETT buffer=#$xon,lun=#LUN.XK; Try hard to send an xon done CALLS ttxon ,<#ttname> ; and try to clear our xoffed state clc ; Success return ; Exit con.br: CALLS ttspee ,<#ttname> ; get the remotes terminal speed mov r0 ,r2 ; save the old speed CALLS setspd ,<#ttname,#50.,#LUN.XK>;try to set it down to 50 baud tst r0 ; did it work ? bne 100$ ; no, forget it WRITETT buffer=#null2,lun=#LUN.XK,size=#2 CALLS setspd ,<#ttname,r2,#LUN.XK>; restore the terminal's speed 100$: clc return .save .psect $PDATA ,D null2: .byte 0,0 .restore con.hl::WRITETT buffer=#hlptxt,lun=#LUN.CO clc return .save .psect rwdata ,rw,d,lcl,rel,con hlptxt: .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 .sbttl dump i/o to a log file ? ; Passed: R5 buffer address ; R1 buffer size dumplo: bit #LOG$CO ,trace ; Is this enabled ? beq 100$ ; No bit #LOG$OP ,trace ; Is it open beq 100$ ; No save ; Save work registers mov r1 ,r2 ; Get the number of characters beq 90$ ; Nothing to do ? 10$: clrb r0 ; Avoid sign extension bisb (r5)+ ,r0 ; Get the next character mov #LUN.LO ,r1 ; Unit number call putcr0 ; Thats it folks sob r2 ,10$ ; Next please 90$: unsave ; Pop registers and exit 100$: clc ; May as well say it worked return ; Bye .save .psect rwdata $xon: .byte 'Q&37,0 $xoff: .byte 'S&37,0 $bel: .byte 'G&37,0 .even .restore .end