Notes on DL: drivers, RMD and Idle Terminal Monitors Edward J. Cetron Center for Biomedical Design 3168 MEB, Univ. of Utah Salt Lake City, Utah 84112 This article was first submitted sometime in Jan. of 1983.... It was lost in the shuffle of newsletter editors and that dry period of Multi-taskers. I finally found it and have resubmitted it. I will apologize in advance for the few instances where the material has become somewhat dated. - EJC I've been meaning to write this article for quite some time now, but, as usual, I just never got the time to type up and organize some of the interesting modifications I've made to me system. Having just returned from the Fall '82 symposium, with all the comments I received about these modifications, I decided now was the time to finally write the article. (Does anyone know a good chiropractor -- my arm still hurts.) DL: drivers and assorted features In an previous issue, some discussion was made about rumors of dual RL02 controllers not working under 11M V4.0. Not having that problem, I simply ignored it. Unfortunately, we had to modify an 11/23 Q-bus system into an 11/23 Q-22 (yes, we know it voids the warranty -- but it is only four wires, or so we thought). Well, the modifications were made, the baseline system was booted and sysgen completed. The newly generated system would not boot - in fact it would run all over memory, and we could not even generate a crash dump. We knew that the hardware worked since the baseline system ran perfectly. And the new system would boot and function properly on our 11/44 system. After a great deal of anguish and frustration, we decided, like all good systems people, to read the driver code. It seems the baseline system is, for compatibility reasons, an 18-bit system. Therefore, the extra 4 bits (for Q-22 or 22-bit Unibus) are ignored and our system would work just fine. But what happens when the new system, configured to be a 22-bit system tries to boot? We learned quite hastily that our RL02's were DMA devices. That is to say the when they wanted to transfer information to memory, they would 'disable' the CPU and, ASSERTING ALL 22-BITS, write directly into memory. But our controllers only used a 16-bit address register -- where were the other bits? It turns out that 2 additional bits are stored in the CSR of the drives. The last four bits are stored by a hardware extension on Unibus machines called the Unibus Map or Unibus Mapping Registers. Since Q-22 systems don't have a Unibus, Digital decided not to give them a Unibus Map (logical, for once). Instead, they designed a new RL02 controller with 5 device registers instead of the standard 4 and dedicated the fifth register for holding those extra 4 bits. Obviously, we didn't have the 5 register controller. And with the new transportablity over all CPU's of 11M V4.0, 11M expected 5 registers -- sort of. After reading the code, we realized how, in general terms, the drivers decide which DMA technique to use: 1. 22-bit system? no --- use old 18-bit DMA (and our baseline worked) yes -- continue 2. Q-22 or Unibus? try to access the fifth register; did it work? yes -- Q-22 so use fifth register for DMA no --- Unibus so ignore the high 4 bits and let the Unibus Map handle it. We now realized that this explained three related problems. First, in our 11/23 system, the driver tried to find the fifth register, failed and then tried to do Unibus DMA. With no Unibus Map, the most significant 4 bits were never set and our DMA transfers went, well... all over the place. Solution: we obtained the RLV12, 5-register controller and all is well. The second problem that it explains is why our 11/44 system's error logger keeps telling me that my controller has 5 registers -- it thinks its on a Q-22 system. Oh well.... I do understand however, that the patch is on its way. It also explains why 2 controllers on a Unibus system might not work. When the addresses of multiple controllers are selected, common practice is to put the CSR's of the second controller immediately after those of the first controller. Well, remember how the driver checks to see if it is on a Q-22 system? Yes, it goes out to the first controller, counts out where the fifth register would be, and lo and behold there is something there. It matters not that this is the first register of the SECOND controller, the driver know thinks it is running on a Q-22 system and things really get messed up. Solution: leave a blank address or four between multiple controllers. RMD on large memory systems (11M V4.0, V4.1, 11M+ V2.1) In the last issue of the Multi-Tasker, it was suggested to use $SYSIZ to modify the size of an RMD display. This is an extremely dangerous procedure and since some tasks and executive routines use this value your system will tend to spontaneously crash quite often (and sometimes quite spectacularly). Our 11/44 has 3.25 Megabytes of memory and the RMD display is quite crowded; if not completely written over itself. At the Center for Biomedical Design, I made a few patches to improve the readability of the RMD display: 1. Treat VT102's, VT105's, and VT125's as 132 columm devices. 2. Move the IN:, OUT: fields up to the SECPOOL area to prevent their being overwritten; this patch will have to be removed for M-plus compatibility. ( I move them past SECPOOL for M-plus ) 3. Provide a command to allow dynamic sizing of the memory page. 4. Include the patches provided in the last issue to use the I/O page when using 11M. The following SLP file will change all the appropriate routines. It is designed to be used with the command file which follows. The general idea is to rename all the appropriate files from .MAC to .OLD (thus preserving the distribution kit for the inevitable DEC patches). The .OLD files are then modified into .MAC form by SLP, assembled and placed in the library (RMD.OLB) out of which RMD.TSK is produced. These files are only templates and some modification of device assignments and UIC's will be necessary depending on your distribution kit. While I did attempt to comment the SLP files, more comments mean more typing in the .SLP files that can be mistyped and ruin the checksum checking. Therefore, it is strongly recommended that you read the newly generated source code -- it is well documented already. If you have any problems please let me know. For those of you wondering, the following .SLP file can be entered as one file or as multiple files. ( NOTE: With a tape drive on order, I will finally have in-house access to a tape drive. I have removed the .SLP files from this article and will instead submit all the .SLP files and a .TSK image for 11MV4.1, and 11M+ V2.1B on the SIG tape in Cincinnati. For those who can't wait, send me a blank tape and a return mailer, postage if you can afford it would be appreciated.) Notes on the Idle Terminal Monitor In our location, the console terminal is always in use. Even though its use is restricted (only myself), we would still like to have it come under the purview of the Idle Terminal Monitor. Somehow, BIGBRO (short for BIG BROTHER, our name for the Monitor) must be able to selectively identify certain tasks as what I call 'ghost' tasks. This will enable BIGBRO to skip those tasks that are normally running from TT0: as the console and allow logging off TT0:. This feature is also needed since MCR... remains 'assigned' to the last terminal that used it. This could prevent the logoff of an idle terminal on an idle system. In addition, I have added some code to set all non-logged in terminals to a site-specific CLI (which may someday appear in these pages) which accepts input from logged out terminals for WHO, RMD, HEL(LO), HELP, and a password controlled ABO(RT). Additional code has been added to reduce to non-privileged any privileged terminal at the issuance of the first warning. I don't have the source for BIGBRO as originally written by Bruce Mitchell so I can't generate a .SLP file. Instead, I've included just my modifications with enough of the existing code so that it can inserted at the correct place (sort of a CMP TI:=SY:USER.MAC, MULTI-TASKER HARDCOPY). First, the changed sections of USER.MAC, each changed section is delimited by asterisks: .title USERMN User Terminal Monitor .IDENT /X01.03/ ; USERMN - User Terminal Activity Monitor for RSX-11M/M+ ; ; ; Author: ; Bruce R. Mitchell ; ; Patterned after the POOL monitor task supplied by Digital ; Equipment Corporation on RSX-11M-PLUS V1.0 Autopatch E. ; ; ; Source Site: ; Engineering Systems and Technology Laboratory ; 3M Company, 3M Center, St. Paul, Minnesota 55144 ; ; Revision History: ; ; 31-dec-81 First version written ; 3-jan-82 Command file generates Ascii strings for time ; 5-jan-82 In-house version released ; 9-jan-82 Decnet HT: support conditionally added ; 11-jan-82 Decus version released ; 20-jan-82 VT100 support conditionalized ; 27-feb-82 Warning messages cleared for active terminals ; 15-mar-82 Correct conditionlization for HT's ; *************************************************************************** ; 21-Jun-82 Modified to fit CBD's 11/44 system ; First warning sets terminal no-priv ; Added software to log off TT0: ; by using 'ghost' tasks ; Added loop counter ; 25-aug-82 resets non-logged in terminals to the ; non-logged in CLI (lgocli) ; ; *************************************************************************** .mcall wtse$ ; wait for single event flag .mcall scli$ ; set cli ; ; *************************************************************************** .page .sbttl Local Variables ; ; ; Local variables ; lopcnt: .word 0 ; loop counter ; ; datbuf: .blkw 8. ; Buffer area for date and time ; *************************************************************************** ; spawn MCR to log out the terminal at address MCRTRM, setting ; event flag SPNEFN on exit or status emmission mcrspn: spwn$ MCR...,,,,,spnefn,,,mcrbye,byelth,,TT mcrbye: .ascii /bye/ ; MCR command to logout terminal byelth = . - mcrbye ; length of command .even setspn: spwn$ MCR...,,,,,spnefn,,,mcrset,setlth,,TT mcrset: .ascii \set /nopriv=ti:\ ; MCR command to de-privilege terminal setlth = . - mcrset ; length of command .even lgoset: scli$ LGOCLI,TT,0 sleep: stse$ efn2 ; goto sleep and wait until next check time spnwai: wtse$ spnefn ; wait for spawn or timeout event flag ; ; ; ghosts = 3 ; number of tasks the are NOT considered active ghstnm: .rad50 /COT.../ ; name of the first task to ignore .rad50 /BIGBRO/ ; ignore us .rad50 /MCR.../ ; and let us forget this too! ; ; ; *************************************************************************** ; warn1: .ascii .ascii /From BIG BROTHER: First idle terminal warning!/<07> .ascii / / .if df v$t100 ; if vt100 support .ascii <133><65><73><61><155> ; esc[5;1m (bold and blink) .endc .even .word time1 ; remaining time .ascii / minutes/ .if df v$t100 .ascii <133><60><155> ;esc[0m .endc .ascii / before forced logout./ .ascii wrn1ln = . - warn1; ; ; .even warnp: .ascii / Terminal now non-privileged/<07> .ascii wrnpln = . - warnp .even ; *************************************************************************** ; .even banzai: .ascii .if df v$t100 ; make a terrible looking display on the screen .ascii <133><61><73><61><110> ; esc[1;1H .ascii /#9/ ; esc#9 .ascii /[>3;11;0;14;132J/ ; clear lines 11-14 inclusive .ascii <133><65><155> ; esc[5m .ascii /[12;26H/ ; move to row 12, col 26 .endc .ascii /From BIG BROTHER: BYE, BYE/ .if df v$t100 .ascii /[13;26H/ .endc .ascii / -- Idle terminal logout/ .if df v$t100 .ascii <133><60><155> ; esc[0m .endc .ascii banzln = . - banzai ; ; *************************************************************************** ; ; ; switch to system state and check active task list ; call $SWSTK,compar ; switch to system state ; and return at compar mov $acthd,r0 ;; r0 points to active task listhead 23$: mov #ghstnm,r3 ;; get basis of ghost names mov #ghosts,r1 ;; get number of ghosts beq 30$ ;; ignore if no ghosts 25$: cmp (r3)+,t.nam(r0) ;; is this task a ghost? beq 26$ ;; maybe, first three letters match inc r3 ;; no, skip second word (three letters) inc r3 ;; ( by two bytes) br 27$ ;; and then go to the next ghost 26$: cmp (r3)+,t.nam+2(r0) ;; do the second three letters match? beq 70$ ;; yes, so ignore it 27$: sob r1,25$ ;; no, so try again... 30$: mov t.ucb(r0),r3 ;; r3 points to UCB for this task mov u.dcb(r3),r1 ;; r1 points to DCB for the UCB ; *************************************************************************** ; set up pointers for next active task and check for list end 70$: mov t.actl(r0),r0 ;; point to next active task tst r0 ;; is this the last task? bne 23$ ;; no, so get more ; *************************************************************************** .if ndf rs.nsl 45$: bis #tm.log,trmdat(r2) ;; set logged-in flag .iff 45$: tst r4 ;; TT: or HT: bne 50$ ;; if an HT:, go to it bis #tm.log,trmdat(r2) ;; set flag for logged-in TT: br 55$ ;; go for next unit 50$: bis #tm.log,netdat(r2) ;; set flag for logged-in HT: .endc 55$: bit #u2.prv,u.cw2(r1) ;; is this unit priv'ed beq 60$ ;; no, look at next unit .if ndf rs.nsl bis #tm.prv,trmdat(r2) ;; set priv'ed flag .iff tst r4 ;; TT: or HT: bne 555$ ;; if an HT:, go to it bis #tm.prv,trmdat(r2) ;; set flag for priv'ed TT: br 60$ ;; go for next unit 555$: bis #tm.prv,netdat(r2) ;; set flag for priv'ed HT: .endc 60$: add #4,r2 ;; r2 points at next terminal flag word inc r5 add d.ucbl(r0),r1 ;; r1 points at next UCB on DCB sob r3,40$ ;; loop for each UCB on DCB ; *************************************************************************** compar: mov #,r0 ; r0 counts down terminal data blocks mov #itt,r5 ; r5 counts down terminal number 10$: bit #tm.log,trmdat(r0) ; is this terminal logged-in? bne 20$ ; if so, skip and process it mov #"TT,lgoset+s.cidv ; set SCLI$ DPB to TT's mov r5,lgoset+s.ciun ; set SCLI$ DPB unit dir$ #lgoset ; set not logged in terminal to lgocli clr trmdat+2(r0) ; not logged-in, clear idle counter br 40$ ; and set up for next data block ; terminal logged in; check for active task ; *************************************************************************** mov #iht,r5 50$: bit #tm.log,netdat(r2) ; is this HT logged-in? bne 60$ ; if so, skip and process it mov #"HT,lgoset+s.cidv ; set SCLI$ DPB to HT's mov r5,lgoset+s.ciun ; set SCLI$ DPB unit dir$ #lgoset ; set not logged in terminal to lgocli clr netdat+2(r0) ; not logged-in, clear idle counter br 80$ ; and set up for next data block ; HT logged in; check for active task ; *************************************************************************** .if df rs.nsl clr r3 ; assume terminal type is TT: .endc mov #"TT,asslun+a.luna ; set device to TT for alun$ mov #"TT,mcrspn+s.pwdn ; set device to TT for spwn$ mov #"TT,lgodev ; set device to TT for console message 10$: tst trmdat+2(r2) ; is this an idle terminal? beq 60$ ; yes, set up for next terminal ; *************************************************************************** 70$: clr r1 ; r1 is HT: number clr r2 ; r2 is offset in HT: data block mov #1,r3 ; assume HT: type is HT: mov #"HT,asslun+a.luna ; set device to HT for alun$ mov #"HT,mcrspn+s.pwdn ; set device to HT for spwn$ mov #"HT,lgodev ; set device to HT for console message 80$: tst netdat+2(r2) ; is this an idle HT: terminal? beq 130$ ; yes, set up for next HT: ; *************************************************************************** ; all terminals processed, back to sleep 140$: dir$ #timdpb ; set wake-up call inc lopcnt ; say we finished another iteration mov lopcnt,r0 ; dir$ #sleep ; and go to sleep jmp tsks ; rise and shine and do it all again ; *************************************************************************** .sbttl warone issue first warning ; ; warone - issue first warning and de-privilege the terminal ; ; inputs: r1 - target terminal number ; r2 - data block offset ; r3 - 0 -> TT:, 1 -> HT: ; ; outputs: terminal flag word is updated ; ; registers are not save or restored ; .if df rs.nsl warone: tst r3 ; is this an HT:? beq 5$ ; a TT: bit #tm.1st,netdat(r2) ; an HT:, has first message been sent? beq 10$ ; no, so send it return ; yes, so don't bother 5$: bit #tm.1st,trmdat(r2) ; a TT:, has first message been sent? .iff warone: bit #tm.1st,trmdat(r2) ; has the first message been sent? .endc beq 10$ ; no, so issue it return ; yes, don't do it again 10$: mov r1,asslun+a.lunu ; load terminal number in alun$ DPB dir$ #asslun ; assign lun 2 to target terminal bcc 20$ ; if it succeeded, issue message return ; if failed, punt 20$: mov #warn1,brodpb+q.iopl ; load message address into qio DPB mov #wrn1ln,brodpb+q.iopl+2 ; load message length into qio DPB dir$ #brodpb ; send out message .if df rs.nsl tst r3 ; is this a TT:, or an HT: beq 25$ ; TT:, so go to TT: code bis #tm.1st,netdat(r2) ; HT:, set first message sent flag bit #tm.prv,netdat(r2) ; was HT: priv'ed beq 40$ ; no, so leave br 30$ ; yes, rejoin common code .endc 25$: bis #tm.1st,trmdat(r2) ; TT:, set first message sent flag bit #tm.prv,trmdat(r2) ; TT:, was TT: priv'ed beq 40$ ; no, so go home 30$: mov r1,setspn+s.pwvt ; load terminal number into spwn$ DPB dir$ #setspn ; de-privilege terminal bcc 35$ ; if ok, good return ; if not, punt 35$: dir$ #spnwai ; wait for spawn to complete mov #warnp,brodpb+q.iopl ; load message address into qio DPB mov #wrnpln,brodpb+q.iopl+2 ; load message length into qio DPB dir$ #brodpb ; send out message 40$: return ; and go home ; *************************************************************************** And now the sections from USERPRE0.MAC (in the same format): ; ; USERPRE - User Terminal Activity Monitor prefix file ; ; Companion source file to USER.MAC ; ; Author: ; Bruce R. Mitchell ; ; Patterned after the POOL monitor task supplied by Digital ; Equipment Corporation on RSX-11M-PLUS V1.0 Autopatch E. ; ; ; Source Site: ; Engineering Systems and Technology Laboratory ; 3M Company, 3M Center, St. Paul, Minnesota 55144 ; ; Revision History: ; ; 1-Jan-82 Source ripped out of SLPRE.MAC ; 2-Jan-82 Warning message bit definitions added ; 21-Jun-82 Modified to fit CBD's 11/44 system ; Added software to log off TT0: ; ************************************************************************ ; Bit masks for terminal and task characteristics ; tm.log = 1 ; terminal logged in tm.tsk = 2 ; task active on terminal tm.mcr = 4 ; terminal CLI is MCR (not used) tm.1st = 10 ; first warning message sent tm.2nd = 20 ; second warning message sent and demoted to ; non-privileged status tm.3rd = 40 ; final warning message sent tm.prv = 100 ; terminal is privileged ; ************************************************************************ These corrections should work. For those who don't like to type (like me) these changes will be on the next SIG symposia tape as I mentioned above. If time permits, I will document up our logged-out terminal monitor and include it also. Maybe even a CLI that enables non-privileged users to RUN programs as a privileged user......