.title k11m41 kermit i/o for RSX11M/M+ v4.1 and 2.1 .ident /5.0.05/ ; Jerry Hudgins (see below) ; define macros and things we want for KERMIT-11 .if ndf, K11INC .ift .include /IN:K11MAC.MAC/ .endc .iif ndf, k11inc, .error ; INCLUDE for IN:K11MAC.MAC failed .enabl gbl ; Copyright (C) 1983 1984 1985 1986 Change Software, Inc. ; ; ; This software is furnished under a license and may ; be used and copied only in accordance with the ; terms of such license and with the inclusion of ; the above copyright notice. This software or any ; other copies thereof may not be provided or other- ; wise made available to any other person. No title ; to and ownership of the software is hereby trans- ; ferred. ; ; The information in this software is subject to ; change without notice and should not be construed ; as a commitment by the author. ; ; .sbttl edits ; 20-Jan-84 09:50:18 BDN Test and fix TTSPEED, SETSPD and BINREAD ; ; 03-Mar-84 Bob Denny 4.2.00 [RBD01] ; Rewrote namcvt(). Eliminated FCS parsing ; in favor of home-brew code which can handle ; the infinite variety of filespecs that may ; crop up when doing DECnet remote file access. ; ; 07-Mar-84 Bob Denny 5.0.00 [Edit trails removed] ; Fair rewrite, particularly of terminal handling. ; Changed within the existing KERMIT-11 architecture, ; which is better suited to RSTS/E (which seems to ; have a lot more terminal & communications options). ; Modes for RSX now allow operation at 9600 baud for ; packet communication. CONNECT is still a problem. ; ; 10-Mar-84 Bob Denny 5.0.01 The method used for CONNECT on RSTS/RSX ; will not work reliably on native RSX at baud rates ; over 1200 on a busy system. The "doconn()" routine ; was rewritten. Now there are 2 separate modules. ; Also, the binrea() function is now used only for ; packet reading, and has been greatly simplified. ; ; 16-mar-84 Brian Nelson ; ; Merged origional K11M41 with Bob Denny's mods. ; ; 11-Dec-85 Robin Miller 5.0.02 Attach the terminal in the TTYINI routine ; (RTM01) so incoming characters are not lost. On a /SLAVE ; terminal, the terminal must be attached so charac- ; ters will be placed in the typeahead buffer. ; Also detach the terminal in the TTYFIN routine. ; ; 11-Dec-85 Robin Miller 5.0.03 Change routine TTPARS to allow device names ; (RTM02) other name XK, TI, or TT for logical names. Also ; check for an error from ALUN$S directive in ASSDEV. ; ; 12-Dec-85 Robin Miller 5.0.04 Change routine ASSDEV to check for logged ; (RTM03) on terminal and to get real device name via GLUN$ ; incase we've assigned a logical name. ; ; ; 25-Dec-85 Brian Nelson ; 08-Feb-86 Steve Heflin ; 10-Feb-86 Brian Nelson ; Finish added Steve Heflin's mods for ATOZ in. ; ; 03-Feb-89 Jerry Hudgins 5.0.05 ; Moved GETPRV call in ASSDEV to ensure priv's are ; up for SF.SMC; will otherwise crash M+ V4.0. Set ; priv's on in EXIT routine also. ; ; ; RSX11M,M+ and P/OS support. ; ; If this looks like it's a mess, it's because it IS. It gets changed ; a little bit here and there (for the past 2 years), and thus has a ; number of contributions and changes from others, and changes due to ; 'NEW' versions of M+ and MicroRSX (ie, things stop working). .sbttl macros .macro moverr val,dst movb val ,-(sp) call $mover movb (sp)+ ,dst .endm moverr .iif ndf, r$rsts, r$rsts = 0 .save .psect CLECTX ,RW,D,GBL,REL,CON .restore ef.tmp = 17 ef.tt = 20 ef.tmo = 21 er.tmo == 176 ; for now, timeout er.nod == 177 ; pseudo error for no data nodata == er.nod .library /LB:[1,1]EXEMC.MLB/ .mcall UCBDF$ UCBDF$ .sbttl data areas .psect $idata rw,d,lcl,rel,con fu$def::.word 0 ; if rms needs the DNA filled in ; The following defaults can be changed in the TKB command file as in: ; ; GBLPAT=K11PAK:DO$APP:1 ; GBLPAT=K11PAK:DO$APP:0 ; GBLPAT=K11PAK:DO$APP:0 do$dte::.word 0 ; if NE, force PROCOMM to default do$app::.word 0 ; if NE, then append to logfiles do$msg::.word 1 ; if EQ, then don't be verbose at times do$tra::.word 1 ; if we look in logical name tables ; for an available terminal. do$alt::.word 1 ; Force SET RSX CON ALT .psect $idata rw,d,lcl,rel,con ; ; Terminal settings and parameter lists for line setting ; ; ; Add mods from Steve Heflin in (SSH and /41/ comments) ; ; Do not include the TC.TBC in the main GMC or SMC as we will ; not know if we are running on M, M+ or Micro-RSX. TC.TBS is ; not available on M. If built on M, the undefined global for ; TC.TBS won't hurt anything. BDN 20-DEC-1985 10:29 savass: ; Remote line saved attributes savdlu::.byte TC.DLU,0 ; /{no}REMOTE /41/ .byte TC.SLV,0 ; /{no}SLAVE .byte TC.BIN,0 ; /{no}READ_PASSALL /45/ .byte TC.NEC,0 ; /{no}ECHO /41/ .byte TC.RAT,0 ; /{no}TYPEAHEAD /41/ .byte TC.8BC,0 ; /{no}EIGHT_BIT /41/ savtbs: .byte TC.TBS,0 ; typeahead buffer size /41/ .byte TC.NBR,0 ; /{no}BROADCAST /41/ diarst = . - savass ; Restore this much for DIAL /45/ savxsp: .byte TC.XSP,0 ; /SPEED:xmt /41/ savrsp: .byte TC.RSP,0 ; /SPEED:rcv /41/ asvlen = .-savass ; /41/ setass: .byte TC.SLV,1 ; /SLAVE=TTnn: .byte TC.NEC,1 ; /NOECHO /41/ .byte TC.RAT,1 ; /TYPEAHEAD /41/ .byte TC.8BC,1 ; /EIGHT_BIT /41/ settbs: .byte TC.TBS,220. ; typeahead buffer size /41/ .byte TC.NBR,1 ; /NOBROADCAST /41/ astlen = .-setass ; /41/ assdon: .word 0 ; flag remote save/set done aslspd: ; Assigned line speed block/41/ aslxsp::.byte TC.XSP,0 ; /SPEED:xmt /41/ aslrsp::.byte TC.RSP,0 ; /SPEED:rcv /41/ iopend: .word 0 ; /36/ lun i/o waiting on savchr: ; Saved line parameters .byte TC.ACR,0 ; /{NO}WRAP .byte TC.FDX,0 ; /{NO}FULLDUPLEX .byte TC.HFF,0 ; /{NO}FORMFEED .byte TC.HHT,0 ; /{NO}TAB .byte TC.NEC,0 ; /{NO}ECHO .byte TC.SLV,0 ; /{NO}SLAVE .byte TC.SMR,0 ; /{NO}LOWERCASE .byte TC.WID,0 ; /WIDTH = n .byte TC.8BC,0 ; /{NO}EIGHTBIT .byte TC.BIN,0 ; /{NO}RPA (BDN 04-Aug-84) savlen = .-savchr savdon: .word 0 ; ; Local line buffer for binary reading ; inilun: .word 0 linbuf: .blkb MAXLNG+ ; /42/ (larger) Buffer itself .even ; /42/ Safety maxlin = .-linbuf ; Maximum read length .even linptr: .word linbuf ; Scan pointer icrem: .rept 15. ; # characters remaining .word 0 .endr privon: .word 0 ; /41/ Save priv on/off status ALSIZE == 440 SDBSIZ == 440 $albuf: .blkb ALSIZE ; /51/ Moved from K11DAT $phnum: .blkb 60 $lnrea::.word RDLIN ; Default for packet reading ; Other r/w data for dialout line set routines /45/ ; .psect rwdata ,rw,d,lcl,rel,con ; read/write data ; Buffers for Autocall modem fix ; /45/ fixti2: .byte TC.DLU,2,TC.ABD,0 ; values we need for a modem /45/ sizti2 = . - fixti2 ; size of buffers for autocall /45/ ; Read only code section .psect $pdata ro,d,lcl,rel,con ; Read-only data ; System Macros used to get/set characteristics for dial out /45/ .mcall qiow$,dir$ ; call in system macroes /45/ ef.rem = 14. ; use remote event flag (14) /45/ set.dlu: qiow$ sf.smc,lun.ti,ef.rem,,,, ; /45/ set.chars: qiow$ sf.smc,lun.ti,ef.rem,,,, ; /45/ rest.chars: qiow$ sf.smc,lun.ti,ef.rem,,,, ; /45/ ; M+3.0 Carrier loss detection dtrast: .byte TC.MHU,0 .word carast dtrclr: .byte TC.MHU,0 .word 0 ; Attributes needed to dialout /45/ diachr: .byte TC.BIN,1 ; binary mode to pass CNTR chars /45/ dialen = .-diachr ; - length of dialout char set /45/ ; Other r/w data .psect $pdata ro,d,lcl,rel,con ; Read-only data datchr: ; Data mode line parameters .byte TC.ACR,0 ; /NOWRAP .byte TC.FDX,1 ; /FULLDUPLEX .byte TC.HFF,1 ; /FORMFEED .byte TC.HHT,1 ; /TAB .byte TC.NEC,1 ; /NOECHO .byte TC.SLV,1 ; /SLAVE .byte TC.SMR,1 ; /LOWERCASE .byte TC.WID,200. ; /WIDTH = 200. .byte TC.8BC,1 ; /EIGHTBIT .byte TC.BIN,0 ; /NORPA datlen = . - datchr ibmmod: .byte tc.bin,1 ; /RPA (need to read XON's) .sbttl xinit - assign & attach command terminal .mcall alun$s ,astx$s ,QIOW$S ,SREX$S ,FEAT$S FE$EXT = 1 .psect $code ; XINIT - Assign and attach the command terminal ; ; This routine assigns and attaches the command terminal (the ; terminal that "ran" this copy of Kermit-11. ; *** N O T E *** Later, this routine should establish a ^C ; AST so that user can abort in-progress file transfers, and ; get Kermit out of server mode without having to send it a ; finish command. I'll wait for Brian to send me his changes ; for graceful transfer abort before I implement this, though. ; ; 23-Dec-85 19:28:43 BDN ; ; For P/OS, M+ v3 and Micro Rsx v3, also do a TLOG (or TRAN) and ; if we we a translation, do an implicit SET LINE. Can be disabled ; by setting DO$TRAN eq to zero. .enabl lsb xinit:: call rmsini ; /53/ Setup SST FEAT$S #FE$EXT ; /56/ See if 4.2 or M+ 3.x bcc 1$ ; /56/ Ok mov sp ,rsx32 ; /56/ Set 3.2 flag SREX$S #1$ ; /56/ See if this is OLD Rsx (3.2) bcs 1$ ; /56/ Must be old RSX clr rsx32 ; /56/ 4.0 or later, or M+ 1.0 and later SREX$S ; /56/ Clear requested exit address 1$: mov #$albuf ,albuff ; /51/ Fill in mov #$phnum ,phnum ; /51/ Fill in clrb @phnum ; /51/ Zero it clr @albuff ; /51/ Init to empty. mov #$cmdbuf,cmdbuf ; /53/ $CMDBUF defined in K11RMS mov #$argbuf,argbuf ; /53/ $ARGBUF defined in K11RMS mov do$tran ,dotran ; /41/ flag for translation mov do$msg ,infomsg ; /41/ flag for msg displaying mov do$app ,logapp ; /41/ Append to logfile flag mov do$dte ,procom ; /50/ Set default for PRO/COMM message tst #dapsup ; /56/ bne 4$ ; /56/ message ; /56/ 4$: message ; /56/ tst do$alt ; /46/ Force alternate code? beq 5$ ; /46/ No mov #xdorsx ,con$ds ; /46/ Yes 5$: mov #xdorsx ,altcon ; /44/ call getsys ; Find out whats running cmpb r0 ,#SY$MPL ; M+? bne 10$ ; No mov sp ,fu$def ; m+, set SY: as def 10$: cmpb r0 ,#sy$pro ; p/os? bne 20$ ; no mov sp ,proflg ; yes, flag it 20$: tst dotran ; /41/ look for logical name beq 30$ ; /41/ no CALLS trntrm ,<#ttname> ; /41/ see if translation exits tst r0 ; /41/ did this succeed ? bne 30$ ; /41/ no MESSAGE ; /41/ inform the user print #ttname ; /41/ print the equivalence name MESSAGE ; /41/ STRCPY #ttdial ,#ttname ; /41/ copy it over here also clr remote ; /41/ and we are local br 40$ ; /41/ continue 30$: tst proflg ; /41/ assume default line for P/OS? beq 40$ ; /41/ not P/OS mov #poscon ,con$ds ; /44/ Force my connect code for p/os STRCPY #ttname ,#xk$dev ; /41/ use xk0: device STRCPY #ttdial ,#xk$dev ; /41/ use xk0: device clr remote ; and we are local clr con8bit ; clear bit 7 MESSAGE ,cr ; tell the user CALLS ttspeed ,<#ttname> ; /54/ Find out current speed tst r0 ; /54/ Can't faile beq 40$ ; /54/ It did MESSAGE ; /54/ A MESSAGE DECOUT r0 ; /54/ Simple MESSAGE ; cr/lf 40$: ALUN$S #LUN.TT,#"TI,#TIUNIT ; Assign command term. QIOW$S #IO.ATT,#LUN.TT,#EF.TT,,#kbiost; Attach it, also QIOW$S #SF.SMC,#LUN.TT,,,,,<#echoch,#2> sub #10 ,sp ; /53/ Get terminal driver support mov sp ,r2 ; /53/ A buffer QIOW$S #IO.GTS,#LUN.TT,,,,, bcs 50$ ; /53/ Oops bit #F2.EIO ,2(r2) ; /53/ Extended IO today? beq 50$ ; /53/ No mov #eioread,$lnread ; /53/ M+, try IO.EIO for version 3 50$: add #10 ,sp ; /53/ Pop buffer clr tcdlu ; don't change tc.dlu call setcc ; enable ^C asts call inqter ; /45/ No, get the terminal type mov r0 ,vttype ; /45/ Done return .save .psect $xkdev ,ro,d,lcl,rel,con echoch: .byte TC.NEC,0 xk$dev::.asciz /XK0:/ .even .dsabl lsb .restore global ; /44/ global global ; /53/ global ; /56/ inqbuf::mov #200. ,-(sp) ; /42/ Assume M+ call getsys ; /42/ M+ today? cmpb r0 ,#SY$MPL ; /42/ If so, large buffering beq 100$ ; /42/ M+ mov #500. ,(sp) ; /42/ Assume P/OS tst proflg ; /42/ P/OS and XK:? bne 100$ ; /42/ Yes, return(500) mov #90. ,(sp) ; /42/ Vanilla RSX11M 100$: mov (sp)+ ,r0 ; /42/ Return buffering available return ; /42/ for LONG PACKET support. setcc:: QIOW$S #io.det,#lun.tt,#ef.tt,,#kbiost QIOW$S #io.ata,#lun.tt,#ef.tt,,#kbiost,,<,0,#ttast> return ttast: cmpb (sp) ,#'c&37 ; control C ? bne 100$ ; no call cctrap ; yes, call handler to check it tst iopend ; /36/ Is a QIO pending for packet? beq 100$ ; /36/ no QIOW$S #IO.KIL,iopend ; /36/ Yes, force an IO.ABO error 100$: tst (sp)+ astx$s ; and exit from ast service global .sbttl ttyini - Save & switch line to data mode ; T T Y I N I ; ; ttyini( %loc device_name ,%val channel_number ,%val ccflag ) ; ; ; input: @r5 .asciz string of device name (Ignored on native RSX) ; 2(r5) channel number (LUN) ; 4(r5) mode bits: (Ignored on native RSX) ; ; output: r0 error codes ; ; On RSX, this routine does dynamic switching of terminal from ; interactive mode(s) to data mode(s). The ttysav(), ttyset() ; and noecho() routines are no-ops ... ; ; It is used only for packet communications. The "doconn()" in ; this module handles the setup and restoration of the terminal ; lines for CONNECT modes. ; ; ** Someday, the whole command terminal and communication line handling ; architecture should be smoothed out and simplified, once Brian and ; I get together and compare notes re: native RSX versus emulated RSX, ; and what is required for compatibility without too much pain ... ; ; Added SREX 22-Jun-84 11:15:46 Brian Nelson ; ; Bob Denny ; .mcall srex$s ,exit$s ttyini::save call getprv ; /41/ May need privs call ttpars ; Get unit number bcs 1$ alun$s 2(r5),r1,r0 ; Assign LUN mov $dsw,r0 ; get the result bcc 2$ ; oops 1$: jmp 10$ ; Too far to branch 2$: clr r0 ; Make return success clr savdon ; not saved tt settings yet cmp 2(r5),#lun.co ; Command terminal (SAFETY) beq 10$ ; (yes, ignore this) QIOW$S #io.att,2(r5),#ef.tt ; Attach the terminal. (RTM01) QIOW$S #sf.gmc,2(r5),#ef.tt,,#kbiost,,<#savchr,#savlen> mov kbiost,r0 cmpb r0,#IS.SUC ; OK? bne 10$ ; (no) mov sp ,savdon ; we have done the save mov 2(r5) ,inilun ; save this lun (BDN) srex$s #abort ; in case server aborted (BDN) tstb handch ; IBM crap (BDN 04-Aug-84) beq 5$ ; no QIOW$S #sf.smc,2(r5),#ef.tt,,#kbiost,,<#ibmmod,#2> ; 5$: QIOW$S #sf.smc,2(r5),#ef.tt,,#kbiost,,<#datchr,#datlen> clr eioinit ; mov kbiost,r0 cmpb r0,#IS.SUC ; OK? bne 10$ ; (no) clr r0 ; Yes - clear r0 = OK QIOW$S #SF.SMC,2(r5),,,,,<#dtrast,#4> ; Set this up for carrier loss 10$: tst proflg ; if a pro/350, ignore errors beq 100$ ; not a 350 clr r0 ; a 350, forget about the errors 100$: unsave call drpprv ; /41/ No privs wanted now return rstsrv::tst inserv beq 100$ call ..abort 100$: return ..abort:call getprv ; /41/ May need privs turned on QIOW$S #sf.smc,inilun,#ef.tt,,#kbiost,,<#savchr,#savlen> call drpprv ; /41/ Don't want privs anymore return abort: call ..abort jmp exit global ; T T Y F I N ; ; ttyfin( %loc device_name ,%val channel_number ) ; ; ; input: @r5 .asciz string of device name (Ignored on native RSX) ; 2(r5) channel number (LUN) ; ; No need for ttyrst() ; ttyfin::call getprv ; /41/ May need privs up now srex$s ; no more abort handling cmp 2(r5),#lun.co ; Command terminal? beq 10$ ; (yes, skip it) QIOW$S #SF.SMC,2(r5),,,,,<#dtrclr,#4> ; Set this up for carrier loss QIOW$S #io.det,2(r5),#ef.tt ; Attach the terminal. (RTM01) tst savdon ; ever save the crap? beq 10$ ; no, don't reset it QIOW$S #sf.smc,2(r5),#ef.tt,,,,<#savchr,#savlen> 10$: call drpprv ; /41/ Don't want privs up clr r0 return ; STUB ROUTINES - Not needed here ; ttrini:: ttrfin:: ttysav:: ttyset:: ttyrst:: noecho:: echo:: clr r0 return .sbttl get terminal name ; G T T N A M ; ; input: @r5 address of 8 character buffer for terminal name ; output: .asciz name of terminal .mcall glun$s gttnam::save ; save temps please mov @r5 ,r3 ; point to output buffer please sub #20 ,sp ; allocate a buffer for GLUN$S mov sp ,r2 ; point to it please glun$s #lun.tt ,r2 ; try it cmpb @#$DSW ,#is.suc ; did it work ? bne 90$ ; no, return the error code please movb g.luna+0(r2),(r3)+ ; get the device name next movb g.luna+1(r2),(r3)+ ; both bytes of it please clr r1 ; get the unit number next please bisb g.lunu(r2),r1 ; simple clr r0 ; now compute the ascii name div #10 ,r0 ; simple (in octal please for RSX) mov r1 ,-(sp) ; save the low order unit number cmp r0 ,#7 ; unit number > 77 octal ? blos 10$ ; no mov r0 ,r1 ; yes, do it again please clr r0 ; simple div #10 ,r0 ; and so on add #'0 ,r0 ; convert to ascii please movb r0 ,(r3)+ ; get the high part copied mov r1 ,r0 ; and now put the next digit back 10$: mov (sp)+ ,r1 ; get the low digit back now add #'0 ,r0 ; convert to ascii add #'0 ,r1 ; likewise movb r0 ,(r3)+ ; move the unit number in now movb r1 ,(r3)+ ; at last .... movb #': ,(r3)+ ; please insert a colon: clrb @r3 ; make it .asciz clr r0 ; no errors br 100$ ; exit 90$: moverr @#$dsw ,r0 ; get the directive error code 100$: add #20 ,sp ; pop glun$s buffer unsave return .sbttl Vanilla read from command terminal ; K B R E A D ; ; Read a line from the command terminal (80 characters max) ; ; Input: @r5 Address of 80 character buffer ; ; Output: r0 = 0 if OK, else error code ; r1 = Number of characters if OK, else 0 ; ; Echoes a on completion to counter Dave Cutler's old ; FORTRAN record processing view of the world. kbread:: QIOW$S #io.rvb,#5,#ef.tt,,#kbiost,,<@r5,#80.> clr r0 ; assume no errors mov kbiost+2,r1 ; return bytecount in r1 cmpb kbiost ,#is.suc ; successful read ? beq 100$ ; yes clr r1 ; no data please moverr kbiost ,r0 ; return the error 100$: print #lf1 return .save .psect $PDATA ,D lf1: .byte lf,0 .restore .sbttl terminal read/write binary mode ; B I N R E A ; ; binread( %val channel_number, %val timeout ) ; ; ; input: @r5 channel number ; 2(r5) timeout (if -1, then no wait) (do this for RSX??) ; ; output: r0 error ; r1 character read ; ; This version uses "normal" reading, as KERMIT sends its packets ; ending in its "EOL" character, which we need to be a . This ; makes reading packets a piece'o cake. We simply buffer lines ; here and scan off characters as needed. Terminal modes have ; been set for reasonably low driver overhead. ; ; No longer used by CONNECT ; pakrea:: binrea::mov @r5 ,iopend ; /36/ save lun i/o is waiting on tstb handch ; doing ibm style xon handshaking BDN beq 5$ ; then we must do single char qios BDN call xbinrea ; do that and exit BDN br 100$ ; /36/ exit 5$: save mov @r5 ,r2 ; lun to use today asl r2 ; fix it for word indexing 10$: tst icrem(r2) ; Anything remaining in current line? bne 40$ ; (yes) jsr pc ,@$lnread ; Call someone to read data bcs 50$ ; (read error) br 10$ ; Try again 40$: clr r1 ; Move next char unsigned ... bisb @linptr,r1 ; ... into r1 inc linptr ; Advance pointer dec icrem(r2) ; Decrement # characters remaining clr r0 ; Success 50$: unsave 100$: clr iopend ; /36/ i/o no longer pending return ; Return ; ; RDLIN - Local read routine ; ; Inputs: ; @r5 LUN to read on ; 2(r5) timeout, seconds ; ; Outputs: ; C-bit clear Successful read (something read before timeout) ; icrem = number of characters in this line ; linptr -> 1st character in the line ; ; C-bit set Failed ; R0 = error code ; icrem = 0 .mcall mrkt$s ,wtse$s ,qiow$s rdlin: clr icrem(r2) ; Reset buffer counter mov #linbuf,linptr ; Reset scan pointer 10$: clr r0 ; Assume no timeout mov 2(r5),r1 ; R1 = timeout in seconds ble 20$ ; (no timeout) add #9.,r1 ; Round up to nearest 10 second clicks div #10.,r0 ; Convert to 10 sec. clicks 20$: tst proflg ; pro/350? bne 25$ ; yes tst chario ; force pro/350 style reads today? bne 25$ ; yes tstb parity ; /39/ must check if TTDRV may never beq 24$ ; /39/ see it's to terminate the cmpb parity ,#PAR$NO ; /39/ line. Use a read with terminator beq 24$ ; /39/ QIO if parity is on. br 25$ ; /41/ IO.RTT did not work ;-/41/ mov #,r1 ; /39/ ;-/41/ QIOW$S r1,@r5,#ef.tt,,#kbiost,,<#linbuf,#maxlin,r0,#tt$trm> ; /39/ ;-/41/ br 30$ ; /39/ 24$: QIOW$S #,@r5,#ef.tt,,#kbiost,,<#linbuf,#maxlin,r0> br 30$ 25$: call getprv ; /41/ May need for SF.GMC call clr -(sp) ; get the typehead buffer size mov sp ,r1 ; point to the parameter area movb #tc.tbf ,@r1 ; we want amount in the buffer QIOW$S #sf.gmc,@r5,#ef.tt,,,, movb 1(r1) ,r1 ; get the typeahead size bne 26$ ; we have something to get there inc r1 ; nothing, wait for one character 26$: QIOW$S #,@r5,#ef.tt,,#kbiost,,<#linbuf,r1,r0> tst (sp)+ ; pop sf.gmc buffer please call drpprv ; /41/ Drop privs if need be 30$: movb kbiost ,r0 ; /41/ cmpb r0 ,#IE.DNR ; /45/ Did we drop carrier ? bne 31$ ; /45/ No mrkt$s #2,#1,#2 ; /45/ Yes, suspend for 1 second wtse$s #2 ; /45/ ... br 40$ ; /45/ Treat as timeout at upper lev 31$: cmpb r0 ,#IS.TMO ; timed out on the read ? beq 40$ ; yes cmpb r0 ,#IE.ABO ; /36/ from IO.KIL on control C ast? beq 40$ ; /36/ yes, treat as a timeout then cmpb r0 ,#IE.EOF ; /41/ End of file today (control Z)? beq 80$ ; /41/ Yes, return control Z and 1 byte cmpb kbiost+1,#33 ; /47/ Was \033 the terminator? beq 80$ ; /41/ Yes, Again return control Z cmpb linbuf ,#'Z&37 ; /41/ P/OS style reads and control Z? beq 80$ ; /41/ Yes, exit tst r0 ; Some kind of success? bmi 90$ ; no mov kbiost+2,icrem(r2) ; Yes, set up number of characters mov #linbuf,r1 ; R1 --> line buffer add icrem(r2),r1 ; R1 --> first free byte at end of line movb kbiost+1,(r1) ; Get possible terminator character beq 35$ ; (none) inc icrem(r2) ; Adjust for terminator 35$: clrb (r1) ; Null terminate just for grins clr r0 ; Clear r0 and C-bit return ; Finished 40$: movb #er.tmo ,r0 ; return timeout error code clr icrem(r2) ; just to be safe sec ; say it failed return 80$: movb #'Z&37 ,linbuf ; /41/ EOF or Escape sequence, return mov #1 ,icrem(r2) ; /41/ control Z and char_count == 1 clc ; /41/ success return ; /41/ exit 90$: clr icrem(r2) ; to be safe sec ; Error return ; bye .sbttl Extended I/O read for M+ and MicroRsx version 3.x .enabl lsb ; Added 27-Jun-86 13:24:18 Brian Nelson ; ; Now that I finally have an 11/73 running M+, I can do stuff ; like this. E$MOD1 = 0 ; Modifier word 1 E$MOD2 = 2 ; Modifier word 2 E$BUFF = 4 ; Buffer address E$LEN = 6 ; Buffer length E$TMO = 10 ; Timeout (in seconds here) E$PRM = 12 ; Prompt address E$PRML = 14 ; Prompt length E$PRMV = 16 ; Prompt VFC E$TT = 20 ; Terminator table address E$TTL = 22 ; Terminator table length E$DFD = 24 ; Default data address E$DFDL = 26 ; Default data length .save ; Save current code psect .psect rwdata ,d ; New psect .even ; Insure eiojnk: .word 0 eiolst: .word 0,0,0,0,0,0,0,0,0,0,0,0,0 ; Itemlist for IO.EIO eioios: .word 0,0,0,0 eioini: .word 0 eiochr: .byte TC.BIN,0,TC.PTH,0 eiosav: .byte TC.BIN,0,TC.PTH,0 $$eiol = . - eiosav .restore ; Restore old psect eiorea::mov r3 ,-(sp) ; Save please tst eioini ; Need to set chars for EIO? bne 10$ ; No (reset to zero in TTYINI) mov sp ,eioini ; Yes, change to /NORPA and /PASTHRU tstb handch ; Hand shaking in effect? bne 10$ ; Yes, leave TC.BIN on please call getprv ; May need privs on QIOW$S #SF.GMC,(r5),#EF.TT,,,,<#eiosav,#$$EIOL> QIOW$S #SF.SMC,(r5),#EF.TT,,,,<#eiochr,#$$EIOL> call drpprv ; Drop them now. 10$: clr ICREM(r2) ; Reset buffer counter mov #linbuf,linptr ; Reset scan pointer mov #eiolst ,r3 ; The itemlist mov 2(r5) ,E$TMO(r3) ; Insert the timeout please mov #linbuf ,E$BUFF(r3) ; Insert the buffer address next. mov #maxlin ,E$LEN(r3) ; Insert the buffer size also. mov #TF.TMO ,E$MOD1(r3) ; Insert desired read modifiers. tst chario ; Do we read EXACTLY whats in buffer? bne 15$ ; Yes. tstb parity ; Is parity on ? beq 20$ ; No, wait for terminators cmpb parity ,#PAR$NO ; Well? beq 20$ ; Ok. Otherwise, read typeahead ONLY 15$: clr E$TMO(r3) ; Yes, later we will not timeout first bis #TF.RAL ,E$MOD1(r3) ; Also, we want everything AS IS! ; 20$: QIOW$S #IO.EIO!TF.RLB,(r5),#EF.TT,,#eioios,,<#eiolst,#30> bcs 90$ ; The directive completely died movb eioios ,r0 ; Get the QIO result. cmpb r0 ,#IE.IFC ; Did it die because of this beq 90$ ; Yes, reset to old read mode. cmpb r0 ,#IE.ABO ; Did the ^C ast routine do IO.KIL beq 80$ ; Yes, return(TIMEOUT) cmpb r0 ,#IE.DNR ; Do we lack carrier now? beq 70$ ; Yes, sleep a moment, return(TMO) cmpb r0 ,#IE.EOF ; Well, what about END of FILE? beq 60$ ; Thats it, return a control Z tst r0 ; Did we get ANY kind of success? bmi 90$ ; No, reset reader address, redo. cmpb eioios+1,#33 ; Did we get ESCAPE as terminator? beq 60$ ; Yes, also treat as control Z cmpb linbuf ,#'Z&37 ; Does the buffer START with ^Z? beq 60$ ; Yes, same thing. cmpb r0 ,#IS.TMO ; Success with a TIMEOUT? bne 30$ ; No tst eioios+2 ; Yes, was there ANY data present? bne 30$ ; There was data, return it please. tstb E$TMO(r3) ; No data, but did we want only the bne 80$ ; typeahead that was there? No mov 2(r5) ,E$TMO(r3) ; Yes, stuff a REAL timeout in. mov #1 ,E$LEN(r3) ; And only ONE character this time. bis #TF.RAL ,E$MOD1(r3) ; Insure no waits for terminators. br 20$ ; Try the read over again now. ; 30$: mov eioios+2,ICREM(r2) ; Return the size of the read now. mov #linbuf ,r1 ; Get the buffer address add ICREM(r2),r1 ; And point to the end of it. movb eioios+1,(r1) ; Get possible terminator character beq 40$ ; (none) inc ICREM(r2) ; Adjust for terminator 40$: clrb (r1) ; Null terminate just for grins clr r0 ; Clear r0 and C-bit br 100$ ; Exit at last.... ; ; 60$: movb #'Z&37 ,linbuf ; Force a control Z to be returned inc ICREM(r2) ; Return exactly ONE character. clc ; Successfull br 100$ ; Exit ; 70$: MRKT$S #2,#1,#2 ; Lost carrier, suspend for a WTSE$S #2 ; moment and return(TIMEOUT) ; Drop through to timeout 80$: movb #ER.TMO ,r0 ; Return timeout error code sec ; Say the read failed br 100$ ; And exit ; 90$: mov #rdlin ,$lnread ; Total failure, switch readers. call getprv ; May need privs on QIOW$S #SF.SMC,(r5),#EF.TT,,,,<#eiosav,#$$EIOL> call drpprv ; Drop them now. clc ; Force caller to try again. 100$: mov (sp)+ ,r3 ; Restore r3 return .dsabl lsb .sbttl BINWRITE(&buffer,size,channel) ; 0(r5) Buffer address ; 2(r5) buffer size ; 4(r5) channel number ; output: r0 error code ; Edit: /40/ 16-Dec-85 14:58:01 BDN Set timer in case line xoffed .mcall mrkt$s ,cmkt$s ,QIOW$S ,astx$s ; /40/ .enabl lsb ; /40/ pakwri:: binwri::mov 4(r5) ,310$ ; /40/ Registers saved in ASTs? mrkt$s #ef.tmo,#7,#2,#200$ ; /40/ start 7 second timeout QIOW$S #io.wal,4(r5),#ef.tt,,#kbiost,,<@r5,2(r5)> cmpb kbiost ,#IE.ABO ; /41/ Did the timeout occur? beq 90$ ; /41/ Yes, try again cmkt$s #ef.tmo,#200$ ; /40/ write ok, cancel timer br 100$ ; /40/ and exit 90$: QIOW$S #io.wal,4(r5),#ef.tt,,#kbiost,,<@r5,2(r5)> ; /40/ 100$: clr r0 return 200$: QIOW$S #IO.KIL,310$ ; /40/ abort the pending I/O call getprv ; /41/ May need privs up now QIOW$S #SF.SMC,310$,,,,,<#300$,#2> ; /40/ insure line is XON'ED call drpprv ; /41/ Don't want privs anymore tst (sp)+ ; /40/ pop timeout flag and astx$s ; /40/ exit .save .psect $idata rw,d,lcl,rel,con .even 300$: .byte TC.CTS,0 310$: .word 0 .restore .dsabl lsb .sbttl real binary i/o for doing ^X and ^Z things ; X B I N R E A ; ; binread( %val channel_number, %val timeout ) ; ; ; XBINREAD is used in Kermit-11 for the DIAL command to read the ; responses from the modem on a character by character basis, and ; also is called once per packet if in local mode to check for ; typeahead in the form of CTRL E, X or Z to implement graceful ; transfer aborts. While this could be done under M/M+ via an un- ; solicited character AST, that won't work for RT11 and RSTS/E. ; Thus the sampling method (XBINREA called by CHKABO). ; ; /38/ Change QIO timed read to untimed with a MARKTIME (MRKT$S) ; to allow better granularity on the timeout interval. If time- ; out occures, do a IO.KIL ; ; ; input: @r5 channel number ; 2(r5) timeout (if -1, then no wait) (do this for RSX??) ; ; output: r0 error ; r1 character read ; .mcall QIOW$S ,mrkt$s ,cmkt$s ,astx$s xbinre::save ; save a register for a friend clr -(sp) ; allocate a buffer please mov sp ,r2 ; and point to it now clr -(sp) ; allocate a buffer for SF.GMC mov sp ,r3 ; and point to it please cmp 2(r5) ,#-1 ; get without any wait today ? bne 20$ ; no, check for timeouts now movb #tc.tbf ,@r3 ; create a .byte tc.tbf,0 QIOW$S #sf.gmc,@r5,#ef.tt,#50,#kbiost,, cmpb kbiost ,#is.suc ; did the read terminal thing work? bne 90$ ; no tstb 1(r3) ; any data in the typeahead buffer? bne 20$ ; yes movb #nodata ,r0 ; fake a psuedo no data error br 100$ ; and exit 20$: tst 2(r5) ; /38/ a real timed read ? ble 30$ ; /38/ no mov @r5 ,iopend ; /38/ save LUN mrkt$s #ef.tmo,2(r5),#2,#200$ ; /38/ we really want 1 second chuncks 30$: QIOW$S #io.ral!tf.rne,@r5,#ef.tt,#50,#kbiost,, cmkt$s #ef.tmo,#200$ ; /38/ cancel marktime please clr r1 ; get the character now please bisb @r2 ,r1 ; copy it with sign extension! clr r0 ; assume no errors cmpb #is.suc ,kbiost ; did it work ? beq 100$ ; yes, exit cmpb #IE.ABO ,kbiost ; /38/ convert IO.KIL to timeout beq 40$ ; /38/ cmpb #is.tmo ,kbiost ; timeout bne 90$ ; no 40$: movb #er.tmo ,r0 ; yes br 100$ ; bye 90$: moverr kbiost ,r0 ; no, return the error 100$: cmp (sp)+ ,(sp)+ ; pop the 2 buffers please unsave ; from DIRECTIVE errors clr iopend ; /38/ return ; bye 200$: tst (sp)+ ; mark time ast entry QIOW$S #IO.KIL,iopend,#ef.tt ; kill the i/o astx$s ; exit chkabo::CALLS xbinrea ,<#lun.tt,#-1> ; simple read on console terminal tst r0 ; did it work ok ? bne 100$ ; no mov r1 ,r0 ; yes, return ch in r0 please return 100$: clr r0 ; it failed return .sbttl Special routines for command line editor read1c::clr -(sp) mov sp ,r0 QIOW$S #IO.RAL!TF.RNE,#5,#EF.TT,,#kbiost,, cmpb kbiost ,#IS.SUC beq 10$ clrb @r0 10$: movb kbiost ,r0 mov (sp)+ ,r0 cmpb r0 ,#CR bne 100$ mov #LF ,r0 100$: bic #^C377 ,r0 return wrtall::SAVE ; Must use IO.WAL for CLE for mov 2+4(sp) ,r2 ; some versions of RSX11M STRLEN r2 ; Get the string length. QIOW$S #IO.WAL,#5,,,,, ; Dump the string in pass-all mode UNSAVE ; Pop register mov (sp)+ ,(sp) ; Move return address over parameter return ; Exit clrcns::QIOW$S #SF.SMC,#5,,,,,<#can,#2>; Simple return .save .psect rwdata ,d can: .byte TC.TBF,0 .restore .sbttl normal i/o to the terminal ; S T T Y O U ; ; input: 2(sp) buffer address ; 4(sp) buffer length ; output: 'c' set on error ; 'c' clear on no error ; ; ; L $ T T Y O ; ; l$ttyou( %loc buffer, %val string_length ) ; ; input: @r5 buffer address ; 2(r5) buffer length l$ttyo:: save ; save temps here please movb kbiost ,-(sp) ; save old io status mov 2(r5) ,r0 ; string length bne 20$ ; length was passed mov @r5 ,r0 ; no length, assume .asciz 10$: tstb (r0)+ ; move along looking for a null bne 10$ ; none yet so far sub @r5 ,r0 ; get the length dec r0 ; off by one 20$: QIOW$S #io.wvb,#5,#ef.tt,,#kbiost,,<@r5,r0> cmpb kbiost ,#is.suc ; did it work ? bne 90$ ; no, exit with carry set clc ; yes, it worked br 100$ ; exit 90$: sec ; write failed, set error flag and exit 100$: movb (sp)+ ,kbiost unsave ; pop registers that we used return ; and exit sttyou:: mov r5 ,-(sp) mov sp ,r5 add #4 ,r5 call l$ttyo mov (sp)+ ,r5 return l$pcrl::MESSAGE return .sbttl exit kermit and logout ; Logout a server (LOGOUT:) by requesting ...BYE ; Exit Kermit-11 ; ; Steve Heflin's mods added 25-Dec-85 12:46:29 BDN .mcall exit$s ,rpoi$s ,exst$s; /41/ add EXST$S .save .psect $PDATA ,D bye: .rad50 /...BYE/ .restore logout:: tst assdon ; ever slave the line? beq 10$ ; no call rstass ; /41/ restore more things now 10$: RPOI$S #BYE ; request ...BYE br exits ; /41/ exit with status please exit:: tst eioini ; /54/ Extended IO init beq 10$ ; /54/ No Call getprv ; /60/ privs on QIOW$S #SF.SMC,#LUN.AS,#EF.TT,,,,<#eiosav,#$$EIOL> Call drpprv ; /60/ privs off 10$: tst assdon ; ever slave the line? beq exits ; no call rstass ; /41/ restore more things now exits: mov exstac ,r0 ; /41/ get exit status bne 20$ ; /41/ something is there to emit EXIT$S ; /41/ nothing there, exit w/o status 20$: asl r0 ; /41/ shift over 4 bits asl r0 ; /41/ ... asl r0 ; /41/ ... asl r0 ; /41/ ... done cmp exstal ,#15. ; /41/ Will command file line number blos 30$ ; /41/ fit into exit status word ? mov #15. ,exstal ; /41/ No, stuff 15 (10) into it 30$: bisb exstal ,r0 ; /41/ Set bits in from line number EXST$S r0 ; /41/ Exit with status now quochk:: clr r0 ; try to see if the logout will work return dskuse:: mov @r5 ,r0 copyz #nogu ,r0 return .save .psect $PDATA ,D nogu: .asciz /Can't do space enquiry for RSX/ .even .restore .sbttl cantyp cancel typeahead ; C A N T Y P ; ; cantyp(%val channel_number) ; ; input: @r5 device name ; 2(r5) lun ; ; ; Cantyp tries to dump all pending input on a given terminal ; line. cantyp:: save ; use r0 to point into xrb call getprv ; /41/ May need privs now clr -(sp) ; allocate buffer for SF.SMC mov sp ,r1 ; point to it please movb #tc.tbf ,@r1 ; cancel all typeahead please mov 2(r5) ,r0 ; get the channel number please asl r0 ; purge internally buffer chars clr icrem(r0) ; simple asr r0 ; restore lun bne 10$ ; ok mov #5 ,r0 10$: QIOW$S #sf.smc,r0,#ef.tt,,#kbiost,, 100$: tst (sp)+ call drpprv ; /41/ Don't want privs right now unsave ; all done return ; bye ; T T X O N ; ; input: @r5 device name ; 2(r5) lun ; output: r0 error code (really, it will be zero) ; ; ; TTXON cancels xoff on a line ttxon:: save ; use r0 to point into xrb call getprv ; /41/ May need privs turned on clr -(sp) ; allocate buffer for SF.SMC mov sp ,r1 ; point to it please movb #tc.cts ,@r1 ; cancel all typeahead please clrb 1(r1) ; zero means to cancel xoff mov 2(r5) ,r2 ; get the channel number please bne 10$ ; ok mov #5 ,r2 10$: QIOW$S #sf.smc,r2,#ef.tmp,,,, QIOW$S #io.wal,r2,#ef.tmp,,,,<#xon1,#1> 100$: tst (sp)+ unsave ; all done call drpprv ; /41/ Don't want privs anymore clr r0 ; no errors return ; bye .save .psect $PDATA ,D xon1: .byte 'Q&37,0 .even .restore .sbttl get uic ; G E T U I C ; ; input: nothing ; output: r0 current UIC/PPN of the user .mcall gtsk$s getuic:: sub #40 ,sp ; allocate gtsk buffer mov sp ,r0 ; point to the buffer please gtsk$s r0 ; simple mov g.tspc(r0),r0 ; return the uic add #40 ,sp ; pop the buffer and exit return ; Drop/Regain privs for M+ v3 and Micro/Rsx V3 /41/ .mcall GIN$S ; /41/ the macro that does such things drpprv::mov r1 ,-(sp) ; /41/ save a register today clr r1 ; /41/ say we want to drop it all br doprv ; /41/ off to common code now getprv::mov r1 ,-(sp) ; /41/ save a register today mov #-1.,R1 ; /60/ set bit 0 to request privs doprv: mov r0 ,-(sp) ; /41/ Lets not trash r0 this time call getsys ; /41/ insure that it's not virgin 11M cmpb r0 ,#SY$11M ; /41/ old type 11M today ? beq 100$ ; /41/ yes, do nothing tst proflg ; /41/ Also skip for P/OS bne 100$ ; /41/ P/OS, then exit tst #GI.SPR ; /41/ if this is not defined then skip beq 100$ ; /41/ it mov r1 ,privon ; /41/ Save priv on/off status GIN$S #GI.SPR,r1 ; /41/ Set the privs up/down now 100$: mov (sp)+ ,r0 ; /41/ Restore R0 mov (sp)+ ,r1 ; /41/ pop a register now return .sbttl suspend the job for a while ; S U S P E N ; ; suspend(%val sleep_time) ; ; input: @r5 time to go away for .mcall mrkt$s ,wtse$s suspen:: tst @r5 ; nonzero seconds call ? bne 10$ ; yes mrkt$s #ef.tt,2(r5),#1 ; no, sleep passed # of ticks br 20$ ; and now wait for the timeout 10$: mrkt$s #ef.tt,@r5,#2 ; sleep integral # of seconds 20$: wtse$s #ef.tt return .sbttl ttypar set parity stuff for kermit ; T T Y P A R ; ; ttypar( %loc terminal name, %val paritycode ) ; ; input: @r5 address of terminal name ; 2(r5) parity code ; output: r0 error code .if ne ,0 ; we are doing it in software as of .ift ; 28-Mar-84 09:11:18 (BDN) ttypar:: call ttpars ; get the terminal unit number bcs 100$ ; oops 100$: movb @#$DSW ,r0 ; get any errors return .endc chkpar::clr r0 return .enabl lsb ; Inqpar added /53/ Inqpar::SAVE ; Save this one clr -(sp) ; Allocate a buffer call ttpars ; the usual, parse the device name bcs 90$ ; oops ALUN$S #LUN.CO,r1,r0 ; assign the terminal please mov sp ,r1 ; Point to it movb #TC.PAR ,(r1) ; Want to know about parity QIOW$S #SF.GMC,#LUN.CO,,,,, bcs 90$ ; Oops movb 1(r1) ,r0 mov sp ,r0 ; Assume parity tstb 1(r1) ; Is parity set? bne 100$ ; Yes 90$: clr r0 ; No parity or directive error 100$: tst (sp)+ ; Pop buffer UNSAVE ; Restore this one return ; Exit GLOBAL .dsabl lsb .sbttl hangup a terminal, set dtr on a terminal ; T T Y H A N ; ; ttyhan( %loc terminalname ) ; ; input: @r5 address of the terminal name ; output: r0 error code .mcall ALUN$S ,CMKT$S ,MRKT$S ,QIOW$S ttyhan::save MRKT$S #EF.TMO,#2,#2,#200$ ; /41/ Set a timeout up please call getprv ; get privs +SSH tst assdon ; /41/ assign ever done ? bne 5$ ; /41/ Yes call ttpars ; /41/ No, likely we are on P/OS bcs 100$ ; /41/ Parse failed (?) ALUN$S #LUN.AS,r1,r0 ; /41/ Never assigned, do it now QIOW$S #IO.ATT,#LUN.AS ; /41/ 5$: tstb logstr ; /41/if logoff MESSAGE len > 0 +SSH beq 10$ ; /41/no +SSH strlen #logstr ; /41/yes, send logout line +SSH QIOW$S #IO.WLB,#lun.as,#ef.tt,,,,<#logstr,r0,#53> ;/41/ +SSH MRKT$S #ef.tt,#2,#2 ; wait 2 seconds +SSH WTSE$S #ef.tt ; 2 seconds up when ef set +SSH 10$: QIOW$S #IO.HNG,#lun.as,#ef.tt,#50,#kbiost ; /SSH tst assdon ; /41/ Ever reach ASSDEV ? beq 20$ ; /41/ No QIOW$S #IO.DET,#lun.as ; /41/ Likely P/OS, so detach NOW 20$: call rstass ; restore any old line setting +SSH CMKT$S #EF.TMO,#200$ ; /41/ Kill the mark time now moverr kbiost ,r0 unsave 100$: return 200$: QIOW$S #IO.KIL,#LUN.AS ; /41/ We get here on a timeout tst (sp)+ ; /41/ Pop EF ASTX$S ; /41/ Exit from the AST carast: MESSAGE MESSAGE ,CR ASTX$S ; raise DTR on a terminal line ; ; T T Y D T R ; ; ttydtr( %loc terminalname ) ; ; input: @r5 address of the terminal name ; output: r0 error code ttydtr:: call ttpars ; the usual, parse the device name bcs 100$ ; oops 100$: movb @#$DSW ,r0 ; return error code and exit return ; bye ; For INQDTR, see same in K11E80.MAC (RSTS/E version) inqdtr::mov #-1 ,r0 return .sbttl ttspeed get speed for line ; T T S P E E D ; ; input: @r5 name of terminal or address of null for current ; output: r0 current speed ; .psect $pdata splst: .word 0 ,50. ,75. ,110. ,134. ,150. ,200. .word 300. ,600. ,1200. ,1800. ,2000. ,2400. ,3600. .word 4800. ,7200. ,9600. ,19200. ,38400. ,-1 setlst: .word s.0 ,s.50 ,s.75 ,s.110 ,s.134 ,s.150 ,s.200 .word s.300 ,s.600 ,s.1200 ,s.1800 ,s.2000 ,s.2400 ,s.3600 .word s.4800. ,s.7200 ,s.9600 ,s.19.2 ,s.38.4 ,-1 .psect $code ttspee::call getprv ; /41/ May need privs turned on save clr -(sp) ; allocate buffer for SF.GMC clr -(sp) call ttpars ; parse the terminal device name bcs 90$ ; error in device name ? alun$s #lun.co,r1,r0 ; assign the terminal please mov sp ,r2 movb #tc.xsp ,@r2 movb #tc.rsp ,2(r2) QIOW$S #sf.gmc,#lun.co,#ef.tt,,#kbiost,, movb kbiost ,-(sp) movb (sp)+ ,kbiost clr r0 ; assume zero speed cmpb kbiost ,#is.suc ; did the read speed thing work ? bne 90$ ; not really movb 1(r2) ,r2 ; get the speed setting please clr r1 ; find the index into speed table 10$: cmp setlst(r1),#-1 ; reached the end of table yet ? beq 90$ ; yes, exit cmpb setlst(r1),r2 ; a match yet beq 20$ ; yes tst (r1)+ ; no, index := index + 2 br 10$ ; next please 20$: mov splst(r1),r0 ; return decimal of the speed br 100$ ; bye 90$: 100$: cmp (sp)+ ,(sp)+ unsave call drpprv ; /41/ Insure privs are turned off return .sbttl set the speed of a terminal line .mcall astx$s ,cmkt$s ,mrkt$s ,QIOW$S ; S E T S P D ; ; setspd(%loc devicename, %val speed) ; ; input: @r5 device name ; 2(r5) speed ; 4(r5) lun ; output: r0 error code, 255 if invalid speed setspd::save call getprv ; /41/ May need privs turned on mov 2(r5) ,r2 ; the speed mov 4(r5) ,r4 ; save the lun call ttpars ; parse the terminal name bcs 90$ ; oops clr r3 ; match the passed speed to the 10$: cmp splst(r3),#-1 ; speed desired to get the index beq 80$ ; end of the table, invalid speed cmp splst(r3),r2 ; a match yet ? beq 20$ ; yes tst (r3)+ ; no, look again please br 10$ ; next 20$: movb setlst(r3),aslxsp+1 ; /41/ insert the transmitted speed movb setlst(r3),aslrsp+1 ; /41/ insert the received speed also mov #aslspd ,r2 ; /41/ pointer to it alun$s r4,r1,r0 ; assign the terminal please mrkt$s #ef.tmo,#2,#2,#spdtmo ; in case we can't get the device QIOW$S #sf.smc,r4,#ef.tt,#50,#kbiost,, cmkt$s #ef.tmo,#spdtmo ; we got it ok clr r0 ; assume success cmpb kbiost ,#is.suc ; did it work ? beq 100$ ; yes, exit without error 70$: moverr kbiost ,r0 ; no, return the error and exit br 100$ ; and exit with the error code 80$: mov #377 ,r0 ; unknown speed br 100$ ; exit 90$: moverr @#$dsw ,r0 ; error from parse br 100$ 100$: unsave ; bye call drpprv ; /41/ Don't want privs on now return spdtmo: tst (sp)+ ; remove the event flag number QIOW$S #io.kil,r4,#ef.tt,#50,#kbiost movb #ie.abo ,kbiost ; insure that's the error code astx$s ; exit from this timeout ast .sbttl ttpars get unit number from ttname ; T T P A R S ; ; ttpars( %loc ttname ) ; ; output: r0 unit number or 377 for null string ; r1 device name ttpars:: ; NEEDS TO BE GLOBAL(RBD) save ; parse a device name clr r1 ; no device name yet clrb @#$DSW ; set no error as of yet mov #377 ,r0 ; presume no device name mov @r5 ,r3 ; get the string address tstb @r3 ; anything there ? beq 90$ ; no, error ; cmpb @r3 ,#'X&137 ; i may try this on 350 some day(RTM02) ; beq 10$ ; ok (RTM02) cmpb @r3 ,#'A&137 ; must be of the format ?Tnnn: blo 90$ ; ok so far cmpb @r3 ,#'Z&137 ; must be of the format ?Tnnn: blos 10$ ; no cmpb @r3 ,#'A!40 ; must be of the format ?Tnnn: blo 90$ ; ok so far cmpb @r3 ,#'Z!40 ; must be of the format ?Tnnn: bhi 90$ ; no 10$: bisb (r3) ,r1 ; ok, save the first character (RTM02) swab r1 ; and make a place for the next cmpb (r3)+ ,#'T&137 ; Is this possibly "TI:" ? (RTM02) bne 15$ ; If NE, no. (RTM02) cmpb @r3 ,#'I&137 ; passed 'TI:' ? beq 105$ ; return unit of 377 then please cmpb @r3 ,#'I!40 ; passed 'TI:' ? beq 105$ ; return unit of 377 then please ; cmpb @r3 ,#'K&137 ; XK: (?) (RTM02) ; beq 20$ ; yep (RTM02) ; cmpb @r3 ,#'T&137 ; must be of the format TTnnn: (RTM02) ; beq 20$ ; ok so far (RTM02) ; cmpb @r3 ,#'T!40 ; must be of the format TTnnn: (RTM02) ; bne 90$ ; no (RTM02) 15$: cmpb @r3 ,#'A&137 ; Is this possibly uppercase ? (RTM02) blo 90$ ; If LO, no. (RTM02) cmpb @r3 ,#'Z&137 ; Is this really uppercase ? (RTM02) blos 20$ ; If LOS, yes. (RTM02) cmpb @r3 ,#'A!40 ; Is this possibly lowercase ? (RTM02) blo 90$ ; If LO, no. (RTM02) cmpb @r3 ,#'Z!40 ; Is this really lowercase ? (RTM02) bhi 90$ ; If HI, no. (RTM02) 20$: bisb (r3)+ ,r1 swab r1 ; have the device name in r1 now clr r0 ; could use .parse but this is 30$: movb (r3)+ ,r2 ; get the next digit in the string beq 90$ ; hit end of string cmpb r2 ,#': ; end of the device name ? beq 105$ ; yes, exit please cmpb r2 ,#'0 ; in the range '0'..'7' ? blo 90$ ; oops cmpb r2 ,#'7 ; keep checking please bhi 90$ ; bad device name asl r0 ; r0 = r0 * 8 asl r0 ; ditto asl r0 ; and so forth sub #'0 ,r2 ; convert to binary add r2 ,r0 ; and sum the digit in please br 30$ ; next 90$: movb #ie.idu ,@#$dsw ; fake a bad device name and exit sec ; ok br 110$ ; bye 105$: clr @#$dsw ; no errors clc ; success 110$: unsave ; bye return .sbttl assign device ; Fake a device assignment by attaching to a dummy lun. Also ; check for someone else having it via issueing a mark time. ; Thanks to Bob Denny for that one. ; .mcall alun$s ,astx$s ,cmkt$s ,mrkt$s ,QIOW$S ,wtse$s assdev::tst proflg ; if this is a pro/350 we don't beq 1$ ; have to worry about all these clr r0 ; characteristics. return ; simply exit 1$: save call rstass ; /41/ restore possible previous set call getprv ; /60/ restore privs again call ttpars bcc 5$ jmp 100$ 5$: mov r0 ,r3 ; save the unit number please cmpb r3 ,#377 ; local terminal ? bne 10$ ; no alun$s #lun.as,#"TI,#0 ; assign the terminal please br 20$ 10$: alun$s #lun.as,r1,r3 ; assign the terminal please bcc 12$ ; If CC, device is assigned. (RTM02) jmp 100$ ; Else, report the error. (RTM02) 12$: sub #20 ,sp ; Allocate a buffer for glun. (RTM03) mov sp ,r2 ; Set pointer to the buffer. (RTM03) glun$s #lun.as ,r2 ; Get real name of terminal. (RTM03) mov g.luna(r2),r1 ; Copy the device name. (RTM03) movb g.lunu(r2),r3 ; Copy the unit number. (RTM03) mov g.lucw(r2),r2 ; Copy the device char. word. (BDN53) add #20 ,sp ; Pop the glun buffer. (RTM03) bit #DV.F11!DV.COM!DV.MNT,r2; Insure not disk or tape (BDN53) beq 15$ ; Yes (BDN53) movb #IE.IDU ,@#$DSW ; No, force an error please (BDN53) jmp 100$ ; Exit (BDN53) 15$: mov @r5,r0 ; Copy the device name buffer. (RTM03) call fmtdev ; Format the real device name. (RTM03) 20$: clr r2 ; flag if we timed out (RTM03) mrkt$s #ef.tmo,#2,#2,#asstmo ; give 2 seconds to do this (RTM03) QIOW$S #io.att,#lun.as,#ef.tt,,#kbiost mov r2 ,r0 ; did we ever time out beq 25$ ; no jmp 110$ ; yes, return busy device 25$: cmkt$s #ef.tmo,#asstmo ; and cancel the mark time sub #20 ,sp ; allocate a buffer for glun mov sp ,r2 ; and a pointer to it glun$s #lun.tt ,r2 ; get name of the console terminal cmpb r3 ,#377 ; no unit? beq 40$ ; yes, must be TI: cmp g.luna(r2),r1 ; device name of console same as dev? bne 30$ ; no cmpb g.lunu(r2),r3 ; unit number the same ? beq 40$ ; yes 30$: QIOW$S #SF.GMC,#lun.as,#ef.tt,,,,<#savass,#asvlen> ; /41/ more things QIOW$S #SF.SMC,#lun.as,#ef.tt,,,,<#setass,#astlen> ; /41/ ditto Call drpprv ; /60/ drop privs now movb savrsp+1,aslrsp+1 ; /41/ copy to assigned recv speed movb savxsp+1,aslxsp+1 ; /41/ copy to assigned xmit speed mov sp ,assdon ; flag we did the set /slave=ttnn: 40$: add #20 ,sp ; pop glun buffer clr r0 cmpb kbiost ,#is.suc ; did it work beq 110$ ; yes, return error zero cmpb kbiost ,#ie.daa ; ignore already attached errors beq 110$ ; simple to do moverr kbiost ,r0 ; no, get the error code br 110$ ; and exit 100$: moverr @#$DSW ,r0 110$: unsave return asstmo: tst (sp)+ ; remove the event flag number QIOW$S #io.kil,#lun.as,#ef.tt,#50,#kbiost moverr #ie.daa ,r2 ; get the error code and exit astx$s ; exit from this timeout ast rstass: tst assdon ; /41/ If line was ever assigned then beq 100$ ; /41/ we need to reset the prev line clr assdon ; /41/ no longer assigned call getprv ; /41/ insure privs are up QIOW$S #SF.SMC,#lun.as,#ef.tt,,,,<#savass,#asvlen> QIOW$S #IO.DET,#lun.as ; /41/ detach it call drpprv ; /41/ Insure no privs now 100$: return .sbttl fmtdev - Format the real device name. ;+ ; ; fmtdev - Format the real device name. ; ; Inputs: ; R0 = The output buffer. ; R1 = The ASCII device name. ; R3 = The BINARY unit number. ; ; Outputs: ; All registers are preserved. ; ;- fmtdev: save ; Save some registers. (RTM03) swab r1 ; Copy (RTM03) movb r1,(r0)+ ; the (RTM03) swab r1 ; device (RTM03) movb r1,(r0)+ ; name. (RTM03) mov r3,r1 ; Copy the binary unit number. (RTM03) clr r2 ; Set for zero supression. (RTM03) call $cbtmg ; Convert it to octal ASCII. (RTM03) movb #':,(r0)+ ; Finish the device name. (RTM03) clrb (r0) ; And terminate with a null. (RTM03) unsave ; Restore the registers. (RTM03) return .sbttl get date and time .enabl lc .mcall gtim$s ascdat::save mov @r5 ,r0 ; r0 := caller result addr sub #16. ,sp ; make room for result mov sp ,r1 ; result addr for gtim$ gtim$s r1 ; get time and date mov g.tida(r1),r2 ; r2 := day jsr pc ,cnvert ; convert and store day movb #'- ,(r0)+ ; insert dash mov g.timo(r1),r2 ; r2 := month asl r2 add g.timo(r1),r2 ; r2 := 3*month add #mnthtab-3,r2 ; r2 := mnthtab[3*month]@ movb (r2)+ ,(r0)+ movb (r2)+ ,(r0)+ ; store month name movb (r2)+ ,(r0)+ movb #'- ,(r0)+ ; insert dash mov @r1 ,r2 ; r2 := year jsr pc ,cnvert ; convert and store year movb #40 ,(r0)+ ; final space clrb @r0 add #16. ,sp unsave return asctim::save mov @r5 ,r0 ; the desitination sub #16. ,sp ; make room for result mov sp ,r1 ; result addr for gtim$ gtim$s r1 ; get time and date mov #3,r3 ; loop count := 3 add #g.tihr,r1 ; start with hours 1$: mov (r1)+,r2 ; begin loop jsr pc,cnvert ; convert to ascii and store dec r3 ; if done beq 2$ ; then exit loop movb #':,(r0)+ ; else insert colon br 1$ ; end loop 2$: clrb @r0 add #16. ,sp unsave return ; cnvert: internal procedure to convert ; integer in r2 to ascii. cnvert: add #366,r2 ;begin loop tstb r2 bpl cnvert ;end loop add #"00-366,r2 ;convert to ascii swab r2 ;reorder bytes movb r2,(r0)+ ;store digit swab r2 movb r2,(r0)+ ;store digit rts pc .save .psect $PDATA ,D mnthtab:.ascii /JanFebMarAprMayJunJulAugSepOctNovDec/ .even .restore .sbttl systat get list of users logged in sercmd:: systat:: moverr #-1 ,r0 return .sbttl dodir get a reasonable directory printed .save .psect dirctx ,rw,d,lcl,rel,con dirnam: .blkb 120 dirbuf: .blkb 120 diridx: .word 0 dirptr: .word dirbuf dcrlf: .byte 15,12,0 wild: .asciz /*.*;*/ .even .restore ; D O D I R ; ; input: @r5 wildcarded filespec ; output: r0 error code ; ; DODIR prints a directory listing at the local terminal. ; ; ; S D O D I R ; ; Passed: @r5 wildcarded name ; Return: r0 error code, zero for no errors ; r1 next character in the directory listing ; ; SDODIR is called by the server to respond to a remote directory ; command. Instead of the pre 2.38 method of dumping output to a ; disk file and then sending the disk file in an extended replay, ; SDODIR returns the next character so that BUFFIL can use it. ; The routine GETCR0 is actually a dispatch routine to call the ; currently selected GET_NEXT_CHARACTER routine. dodir::save ; /38/ Entirely rewritten STRCPY #dirnam ,@r5 ; copy the filespec to save area call dirini ; initialize things 10$: call dirnex ; get next entry to display bcs 100$ ; error, exit please .print #dirbuf ; ok, dump it br 10$ ; next please 100$: unsave ; exit clr diridx ; clear flag and exit return ; bye sdirin::STRCPY #dirnam ,@r5 ; copy name over clr diridx ; ditto call dirini ; init for CALLS to sdodir bcs 100$ mov #dirbuf ,dirptr ; yes, init pointers please clrb @dirptr ; yes, zap the buffer call dirnex ; preload buffer 100$: return sdodir::save 10$: movb @dirptr ,r1 ; get the next character please bne 20$ ; something was there mov #dirbuf ,dirptr ; reset the pointer clrb @dirptr ; yes, zap the buffer call dirnex ; empty buffer, load with next file bcs 90$ ; no more, return ER$EOF br 10$ ; and try again 20$: inc dirptr ; pointer++ clr r0 ; no errors br 100$ ; exit 90$: mov #ER$EOF ,r0 ; failure, return(EOF) 95$: clr r1 ; return no data also clr diridx ; init for next time through 100$: unsave return .sbttl return next directory entry and init directory dirini: clr diridx ; clear context flag mov #dirbuf ,dirptr ; set pointer up for SDODIR clrb @dirptr ; clear buffer return ; thats all folks dirnex: movb defdir ,-(sp) ; anything in DEFDIR ? bne 10$ ; yes, don't alter it please STRCPY #defdir ,#wild ; nothing, insert *.*;* 10$: CALLS lookup ,<#3,#dirnam,#diridx,#dirbuf> tst r0 ; successfull? bne 20$ ; no strcat #dirbuf ,#dcrlf ; yes, append clr r0 ; strcat returns DST addr in r0 br 100$ ; exit 20$: cmp r0 ,#ER$NMF ; no more files error ? bne 90$ ; no tst diridx ; ever do anything? bne 90$ ; yes mov #ER$FNF ,r0 ; no, convert to file not found 90$: sec 100$: movb (sp)+ ,defdir ; restore DEFDIR return .sbttl fix up error codes $mover: tstb 2(sp) bmi 10$ clr 2(sp) return 10$: neg 2(sp) return .sbttl rsxsys sys command for RSX11M/M+ ; 21-Aug-83 16:12:37 Brian Nelson ; 12-Jan-84 09:54:02 Created from MINITAB v82 source ; 07-Mar-84 21:58:10 Bob Denny - Stop instead of wait, nicer. .enabl gbl .mcall spwn$s ,stse$s ,r50$ .enabl lsb runjob:: mov #cli... ,r0 call rsxsys return runmcr:: mov #mcr... ,r0 call rsxsys return rsxsys:: save QIOW$S #io.det,#lun.tt,#ef.tt,#50,#kbiost mov r0 ,r4 ; save the CLI we want to use sub #12*2 ,sp ; need eight word exit block BDN mov sp ,r2 ; Get address of exit block BDN clr @r2 ; to be safe ? mov 2(r5) ,r1 ; the command buffer address mov r1 ,r3 ; save it strlen r1 ; get the command string length add r0 ,r3 ; point to the end cmpb -(r3) ,#cr ; trailing carriage return ? bne 5$ ; no dec r0 ; yes, fix the length up 5$: mov r0 ,r3 ; save the length clr r0 ; assume no error please spwn$s r4,,,,,#6,,r2,r1,r3 ; do it bcc 10$ ; Ignore error for now moverr @#$DSW ,r0 ; get the error code please QIOW$S #io.att,#lun.tt,#ef.tt,#50,#kbiost print #100$ br 20$ 10$: stse$s #6 ; Stop for task to exit 20$: add #12*2 ,sp ; pop exit status block QIOW$S #io.att,#lun.tt,#ef.tt,#50,#kbiost unsave ; pop registers and exit return .save .psect $PDATA ,D 100$: .asciz <15><12>/Spawn failure for SYS command/<15><12> .even mcr...: r50$ MCR... cli...: r50$ CLI... .restore .dsabl lsb .sbttl spool to printer .mcall print$ ; can we do this with RMS i/o ????? qspool::movb #1 ,r0 return ; CALLS open ,<@r5,2(r5)> ; CALLS rsxspl ,<2(r5)> ;100$: return ; ; ;rsxspl::mov r0 ,-(sp) ; save temps ; mov r1 ,-(sp) ; also this one ; mov @r5 ,r1 ; unit number file is open on ; asl r1 ; get into word offset ; mov fdblst(r1),r1 ; fdb for that file ; clr errsav ; print$ r1,,,#"LP,#1 ; spool file to lp0 now ; bcc 100$ ; moverr f.err(r1) ;100$: mov (sp)+ ,r1 ; pop temps and exit ; mov (sp)+ ,r0 ; ; return ; bye .sbttl detach for the server ; Much simpler for RSX than for RSTS detach::QIOW$S #io.det,#5,#ef.tt,,#kbiost clr r0 return login:: mov 4(r5) ,r0 STRCPY r0,#nologin mov #1 ,r0 return .save .psect $PDATA ,D nologin:.asciz #Can't do REMOTE LOGIN for RSX11M/M+ and P/OS#<15><12> .even .restore .sbttl error MESSAGE text syserp:: save mov @r5 ,r0 call rmserp MESSAGE unsave return syserr:: save ; save a register clr -(sp) ; allocate variable for error # mov sp ,r1 ; and point to it mov @r5 ,@r1 ; if errornumber > 0 bmi 10$ ; then CALLS direrr ,<#2,r1,2(r5)> ; call fiperr(num,text) br 100$ ; else 10$: CALLS rmserr ,<#2,r1,2(r5)> ; call rmserr(num,text) 100$: tst (sp)+ unsave return global .sbttl dodial for the DIAL command .enabl lsb ; This is Steve Covey's code for dialing on XT1 or XT2 on the ; PRO/TMS Telephone Management System. BDN 06-Dec-85 11:00:40 ; ; TMS ; TMS for a Telephone Management System (TMS) on a PRO/350 ; TMS supports lines XT1: or XT2: under P/OS V2 ; TMS ; TMS the DIAL command establishes the phone connection ; TMS assuming that the appropriate SET LINE XTn: and SET SPEED n ; TMS commands have been issued, and that the lun has been assigned ; TMS and attached. ; TMS ; TMS the phone number can consist of the following: ; TMS digits to be dialed ; TMS ! 6 second access pause for dial tone ; TMS !! 40 second access pause for dial tone ; TMS , 2 second delay ; TMS # changes to DTMF if initially pulse mode ; TMS *ABCD other valid DTMF codes ; TMS ^ as the first character causes a "hook flash" ; TMS ()- and spaces ignored. max total number 48 characters .mcall QIOW$S ,alun$s ; TMS ; TMS ef.rem = 14. ; TMS tmsdia::save ; TMS CALLS ttpars ,<#ttname> ; TMS bcs 5$ ; TMS alun$s #lun.ti,r1,r0 ; TMS QIOW$S #io.att,#lun.ti,#ef.rem,,#tmsios ; TMS QIOW$S #sf.smc,#lun.ti,#ef.rem,,#tmsios,,<#smctms,#smclen> ; TMS strlen argbuf ; TMS get length of phone number QIOW$S #io.con,#lun.ti,#ef.rem,,#tmsios,, ; TMS cmpb tmsios,#is.suc ; TMS did it work? beq 10$ ; TMS yes 5$: unsave ; TMS MESSAGE ,cr ; TMS/BDN mov #-1 ,r0 ; TMS/BDN return ; TMS 10$: unsave ; TMS MESSAGE ,cr ; TMS/BDN clr r0 ; TMS/BDN return ; TMS .save .psect $PDATA ,D tmsios: .word 0,0 ; TMS iosb for tms CALLS smctms: .byte xt.dmd ; TMS set data mode .byte xt.ser ; TMS serial data (not codec, dtmf, or voice) .byte xt.dlm ; TMS set dial mode .byte xt.dtm ; TMS DTMF (not pulse 10 or 20, or off hook) .byte xt.dit ; TMS set DTMF intertone time * 10ms .byte 10. ; TMS 100 milliseconds .byte xt.dtt ; TMS set DTMF tone time * 10ms .byte 10. ; TMS 100 milliseconds ; .byte xt.mtp ; TMS set modem type - should default from speed ; .byte xtm.ps ; TMS DPSK - 1200 baud Bell 212 smclen = . - smctms ; TMS .restore .dsabl lsb .sbttl Look in logical name tables for KERMIT$LINEn .mcall tlog$s ,alun$s ,QIOW$S ,cmkt$s ,astx$s ,mrkt$s ; TRNTRM(&return_name) ; Added edit /41/ ; ; Passed: 0(r5) address of where to return first available dev ; Return: r0 zero for success, else directive error code. ; ; ; Look through logical name tables for a free terminal to use. The ; first translation will be on KERMIT$LINEn, where N is null, then ; 1 though NN. Stop on first translation that has a free terminal, ; or when we fail on the translation (IE.LNF). For now, to see if ; the line is free, try IO.ATT with a short marktime to abort the ; attach in case the line is already in use (actually call ASSDEV) ; ; Added edit /41/ 23-DEC-1985 10:20 ; ; Local copy of TLON$S from M+ v3 ; ; Since I may have to do this on M+ 2.1 or RSTS v9, those RSXMAC's ; have TLOG$S but not TLON$S. Thus lets define it here. Note that ; trying to execute TLON or TLOG on old RSX's won't hurt anything, ; they will simply return an error. .MACRO TLON$S MOD,TBMSK,STATUS,LNS,LNSSZ,ENS,ENSSZ,RSIZE,RTBMOD,ERR .MCALL DIR$,MOV$,MVB$,LNMOD$ LNMOD$ MOV$ STATUS MOV$ RTBMOD MOV$ RSIZE MOV$ ENSSZ MOV$ ENS MOV$ LNSSZ MOV$ LNS MVB$ TBMSK,#0 MVB$ #13.,MOD MOV (PC)+,-(SP) .BYTE 207.,10. DIR$ ,ERR .ENDM TLON$S tr$res = 0 tr$nam = 2 tr$uni = 4 trntrm::save ; +/41/ save temp registers sub #10 ,sp ; local r/w things mov sp ,r3 ; base it off of r3 sub #30 ,sp ; allocate a result buffer mov sp ,tr$res(r3) ; and a pointer to it sub #30 ,sp ; allocate buffer for xlate name mov sp ,tr$nam(r3) ; and a pointer to the buffer mov #-1 ,tr$uni(r3) ; 'unit' number counter call getsys ; vanilla RSX 11M today? cmpb r0 ,#SY$11M ; well ? bne 10$ ; no jmp 90$ ; yes, do nothing at all then 10$: STRCPY tr$nam(r3),#ln$nam ; copy the prototype name over tst tr$uni(r3) ; is this the first time through? bmi 30$ ; yes (ie, it's -1) mov tr$uni(r3),r1 ; no, append the 'unit' on logical clr r2 ; so we get a name like KERMIT$LINE2 20$: tstb (r0)+ ; get to the end of the logical bne 20$ ; not yet dec r0 ; r0 --> end of copy of prototype call $cbdmg ; r0 already had address from STRCPY clrb @r0 ; insure .asciz 30$: clr -(sp) ; allocate buffer for returned_size mov sp ,r1 ; and a pointer to it clr -(sp) ; allocate buffer for 'RTBMOD' mov sp ,r2 ; and a pointer to it also strlen tr$nam(r3) ; get length of name to translate tst proflg ; is this P/OS today ? bne 40$ ; yes, use TLOG$S then TLON$S #0,ln$msk,#0,tr$nam(r3),r0,tr$res(r3),#27,r1,r2 br 50$ ; 40$: TLOG$S #0,ln$msk,#0,tr$nam(r3),r0,tr$res(r3),#27,r1,r2 50$: tst (sp)+ ; ignore the returned table number mov (sp)+ ,r1 ; get the length of translated string cmpb @#$DSW ,#IS.SUC ; successfull translation ? bne 70$ ; no 60$: add tr$res(r3),r1 ; success, make name .asciz clrb @r1 ; simple CALLS assdev , ; parse and assign the device cmpb r0 ,#IE.DAA ; device busy today ? beq 80$ ; yes, try next logical tst r0 ; other errors are fatal bne 100$ ; exit STRCPY @r5 ,tr$res(r3) ; success, return device name clr r0 ; success br 100$ ; exit 70$: tst tr$uni(r3) ; translation failure, first time? bpl 90$ ; no, error is fatal 80$: inc tr$uni(r3) ; first time, goto KERMIT$LINE0 jmp 10$ ; next logical name please 90$: clr r0 ; return an error bisb #IE.IDU ,r0 ; return invalid device name 100$: add #10+<2*30>,sp ; pop local buffers unsave ; and pop registers we saved return ; -/41/ exit .save .psect $idata ln$nam::.asciz /KERMIT$LINE/ ; prototype logical name .even ; always please ln$msk::.word 0 ; may want .word IN.SYS!IN.GRP .restore .sbttl dialout line setup routines ; /45/ ; From Steve Heflin, 08-Feb-86 ; ; These SET and RESTORE line characteristics for the DIAL command ; that are special for talking to the modem. These are NOT needed ; for RSTS/E and RT11, so thus are return stubbs to resolve the ; global symbol references. tidias:: ; Setup line for dialout /45/ call getprv ; get privledges /45/ cmpb savdlu+1,tcdlu ; already in dialout mode ? /45/ beq 45$ ; yes, no need to change it /45/ tstb tcdlu ; allowing tc.dlu change? /45/ beq 45$ ; no /45/ movb tcdlu ,fixti2+1 ; adust setting for TC.DLU /45/ dir$ #set.dlu ; issue set /45/ 45$: dir$ #set.chars ; set other attribs. for dialout /45/ call drpprv ; drop privs /45/ return ; /45/ tidiar:: ; Restore remote line attrib. /45/ call getprv ; get privledges /45/ cmpb savdlu+1,fixti2+1 ; if TC.DLU param got changed /45/ beq 50$ ; no, /45/ movb savdlu+1,fixti2+1 ; yes, restore it like it was /45/ dir$ #set.dlu ; issue request /45/ 50$: dir$ #rest.chars ; restore remote line attributes /45/ ; that could have been lost when /45/ ; carrier was detected /45/ call drpprv ; drop privs /45/ return ; /45/ .sbttl find out kind of terminal ; INQTER 12-Feb-86 14:51:00 Brian Nelson ; ; This returns VT100 for all VT1xx and VT2xx terminals. ; Since we don't treat VT200's different, why bother. ; If TC.ANI is unknown on old RSX's, SF.GMC will simply ; stop there, returning only TC.TPP. For applications ; that REALLY need to know the terminal type, take out ; the check for TC.ANI. Including the TC.ANI helps when ; Digital adds new VTxxx terminals. .enabl lsb inqter: save ; /45/ Get the type of terminal clr -(sp) ; /45/ A small buffer to use clr -(sp) ; /45/ Another one mov sp ,r2 ; /45/ A pointer to that buffer movb #TC.TTP ,@r2 ; /45/ Characteristic to read movb #TC.ANI ,2(r2) ; /45/ Does this one work on old RSXs qiow$s #SF.GMC,#5,,,,, ; /45/ Get RSX to tell us now bcs 90$ ; /45/ Failed, return TTY tstb 3(r2) ; /45/ See if ANSICRT bne 20$ ; /45/ YES, exit now with VT100 mov #200$ ,r1 ; /45/ Check for it 10$: tstb @r1 ; /45/ End of the list beq 90$ ; /45/ Yes, return TTY cmpb (r1)+ ,1(r2) ; /45/ A match ? bne 10$ ; /45/ No, exit please 20$: mov #VT100 ,r0 ; /45/ Yes, return(VT100) br 100$ ; /45/ Exit 90$: clr r0 ; /45/ No match, return(TTY) 100$: cmp (sp)+ ,(sp)+ ; /45/ Pop buffer and exit unsave ; /45/ Pop registers and exit return ; Note: If the PRO/350 is to actually be used for, say, editing ; or if it is to use the Kermit-11 connect code's GRAY key re- ; mapping, then we should ALWAYS map T.BMP1 to a VT100. This is ; a problem, however, as the value of T.BMP1 is the same as it ; is for T.V2XX. At least, according to the Micro-RSX doc vt2xx ; code is 35 (8), actual task build shows T.BMP1 to be 35 also. ; Please note the the PRO is NOT totally compatible with VT2xxs ; TC.BMP1 is the PRO terminal type (Bit MaPped) .save .psect $PDATA ,D 200$: .byte T.V100 ,T.V101 ,T.V102 ,T.V105 ,T.V125 ,T.V131 .byte T.V132 ,T.BMP1 ,T.V2XX .byte 0 .even .restore .dsabl lsb .end