TITLE H19WHO -- WHOLINE for H19's ; Tuesday Nov 14,1978 5:18 FQ+6D.15H.18M.26S. -*- Midas -*- a=1 b=2 c=3 d=4 e=5 f=6 t=7 tt=10 j=11 ; (Internal) Job number tty=12 ; TTY number i=13 ; Random index reg, used for referencing ; various system symbols (eg, IOTTB) q=14 who=15 mode=16 p=17 tyoc==1 loc 100 ;100$G will clear line 25 and die jrst killme pdl: block 100 tyobuf: block 100 tyocnt: 0 tyobp: 441000,,tyobuf tyoibp: 441000,,tyobuf clktim:0 ? 0 ;2 words to pass to .REALT ljclbuf==10 jclbuf: block ljclbuf tsint: loc 42 jsr tsint loc tsint 0 ? 0 jrst tsint0 ;jump to pure place tyohak: movei c,-tyotab-1(t) tyo: movei d,%tdqot idpb d,tyobp idpb c,tyobp aos tyocnt aos tyocnt popj p, define space pushj p,tyotab+40 termin define .strt string jsp t,astrt [asciz string] termin astrt: hrrz a,(t) aos t push p,t ;;; Asciz string in A. strt: hrli a,440700 setz b, movei d,%TDQOT strt0: ildb c,a jumpe c,[addm b,tyocnt ? popj p,] idpb d,tyobp aos b idpb c,tyobp aoja b,strt0 ;;; 6bit of something in A. Clobbers B and C. ;;; Outputs the full field (6 chars) 6type: movei b,6. addm b,tyocnt addm b,tyocnt 6type0: movei c,%tdqot ;%tdQOTe them idpb c,tyobp ldb c,[360600,,a] addi c,40 idpb c,tyobp rot a,6 sojg b,6type0 popj p, ;;; Type out a sixbit frob, not in a fixed field... u6type: setz b, u6typ0: jumpe a,[addm b,tyocnt ? addm b,tyocnt ? popj p,] movei c,%tdqot idpb c,tyobp ldb c,[360600,,a] addi c,40 idpb c,tyobp lsh a,6 aoja b,u6typ0 cpopj: popj p,cpopj tyotab: repeat 177,jsp t,tyohak define chrout \ch pushj p,tyotab+"ch termin go: .call [setz ? sixbit |OPEN| ? movsi .uao+%tjsio ? movei tyoc setz [sixbit |TTY|]] .lose %lsfil move p,[-77,,pdl] .scalar gubbish,machine,sysver pushj p,jclhak ;hack jcl flags, etc. .call [setz ? sixbit |sstatu| ? movem gubbish ? movem gubbish movem gubbish ? movem gubbish ? movem gubbish movem b ? setzm a] .lose %lssys camn b,machine came a,sysver pushj p,purif .scalar debug,forgot skipn debug skipe forgot jrst forgut .value [asciz |:forget |] setom forgot forgut: movei a,5*60. pushj p,setclk .suset [.simask,,[%pirlt]] ;enable real time ints jrst go2 ;Don't hang the first time around setclk: movem a,clktim move a,[<%rlfls\%rlset>,,clktim] ;flush prev, set new rate .realt a, ;start the clock jfcl popj p, go1: move a,@ttysts camn a,@ttysts hang: .hang ;hang until this changes, or timer goes off jumpe a,go2 ;go on if timer went off ;here if camn preceding .HANG skipped ;We check only the rh of TTYSTS, because the lh (%TSACT, etc.) ;can change lots - Who wants to see LISTEN then SLEEP then TTYI ;after typing alt when running EMACS on a non-fci terminal?? xor a,@ttysts ;compare right halves = owner job hrrzs a ;keep rh only jumpe a,go1 ;go rehang if owning job is unchanged go2: .suset [.rcnsl,,tty] ;get tty number we're on jumpl tty,[ ;If no tty now, sleep, waking very infrequently movei tty,30.*10. ;until we do have a tty. .sleep tty, jrst go2] ;;; Check to see if the system is full. If so, be obnoxious... .scalar cheque ;I suppose it's initialized to zero? sosle cheque ;do this check every 12. times or so jrst go1.1 movei j,12. movem j,cheque setz j, move a,maxj imul a,lublk came a,@usrhi jrst go1.1 chequ0: skipn @uname ; free job slot? jrst go1.1 ; Yes, continue on. add j,lublk came j,a jrst chequ0 ;;; Ok, system is full - let's give him some grief. .strt |jx1Y8 lpThe system is full - you should flush your WHOLIN job.kq| pushj p,output jrst go1 go1.1: hrrz j,@ttysts ;get internal job index of tty's owner move a,@uwho1 ;collect some who variables movem a,who1 move a,@uwho2 movem a,who2 move a,@uwho3 movem a,who3 skipge who1 ; bit 4.9 suppresses wholine entirely jrst whoclr ; for that job. .strt |jx5x1Y8 | ; Otherwise, go to bottom of the screen, .scalar invers skipe invers ;do we want inverse video? Skip if not. jrst [.strt |p| jrst .+1] move b,@ttyopt ; maybe clear the line, if we have over- movei a,[asciz |l|] ; strike; maybe just overstrike... tlne b,%toovr ; Clear line if we have overstrike pushj p,strt pushj p,gotime ; Type out the time of day space pushj p,tuname ; uname (Skips if it DOESN'T output, so we space ; won't output the space.) pushj p,tjname ; jname space pushj p,tsname ; sname space pushj p,tpages space pushj p,jobsts ; job status space pushj p,truntm ; runtime space pushj p,gowho ; and whatever the who variables dictate. move t,@ttyopt ; If we didn't cleol before, then we need movei a,[asciz |K|] ; to now. tlnn t,%toovr pushj p,strt .strt |qy5k| ; restore cursor position pushj p,output jrst go1 whoclr: .strt |jx5x1Y8 Ky5k| ;Clear the wholine completely pushj p,output jrst go1 output: move a,tyoibp ; and ZAP! Instant wholine. .call [setz ? sixbit |SIOT| ? movei tyoc ? a ? setz tyocnt] .lose %lsfil setzm tyocnt move a,tyoibp movem a,tyobp popj p, ;;; These are the various subroutines for printing different things. ;;; Note about GOTIME: Although .RPLDTIM is claimed to be the same as ;;; a .pdtime and a .ryear (although the time is in different units, ;;; the .rlpdtime giving it in seconds and .pdtime in 60th secs), ;;; the time given by .PDTIME is the actual number of 60th secs since ;;; the beginning of the year, and .RLPDTIM gives the number of seconds ;;; which it would be if the actual time (eg daylight savings) were ;;; the standard time. (Sick, eh?) Thus, when one gets the information ;;; about whether or not daylight savings time is in effect by using ;;; .rpldtime instead of .pdtime, that information isn't needed to get ;;; the actual local time. (sigh) gotime: .rlpdtime a, idivi a,86400. movei who,(b) jrst wtim3 tuname: move a,@uname .suset [.runame,,b] came a,b jrst u6type popskp: aos (p) cpopskp: popj p,popskp tjname: move a,@jname jrst 6type tsname: move a,@usysnm jrst 6type ;;; Type out the page state (as pages-in/pages-total). tpages: push p,tyocnt move e,@nmpgs move a,@nswpgs subm e,a movei f,10. caig a,99. space caig a,9. space pushj p,numprt chrout / move a,e pushj p,numprt chrout K pop p,t addi t,8. tpags0: camg t,tyocnt popj p, space jrst tpags0 .scalar who1,who2,who3 ;;; NO MORE VARIABLES PAST THIS POINT! We want the variables to stay in ;;; the first page, will purify the second (if there is a second). variables gowho: ldb mode,[370300,,who1] ; Now, print out the left half of .WHO2 hlrz who,who2 ; as directed pushj p,@whotab(mode) ldb c,[240700,,who1] ; Character to print? jumpn c,[movsi t,1000 ; Double it? tdne t,who1 pushj p,tyo ; Yes! Lots of Gubbish! pushj p,tyo jrst .+1] movsi t,200000 ; Print a space after the left 1/2? tdnn t,who1 space hrrz who,who2 ldb mode,[340300,,who1] pushj p,@whotab(mode) ; Right half of .WHO2 movsi t,2 tdnn t,who1 space hlrz who,who3 ldb mode,[170300,,who1] pushj p,@whotab(mode) ldb c,[040700,,who1] jumpn c,[movei t,4000 tdne t,who1 pushj p,tyo pushj p,tyo jrst .+1] movsi t,1 tdnn t,who1 space hrrz who,who3 ldb mode,[140300,,who1] jrst @whotab(mode) whotab: cpopj ; 0 - Ignore this field. wdate ; 1 - Date in packed form wtim40 ; 2 - time, as HH:MM:SS.T (given in 40ths) wtim2 ; 3 - time, as HH:MM:SS (given in 1/2ths) woctal ; 4 - Octal 1/2 word wdecimal ; 5 - Decimal 1/2 word wsix ; 6 - 3 sixbit chars cpopj ; 7 - unused (error?) ;;; More crufty routines. ;;; Type out a 2 digit decimal number. If it is < 10., a leading 0 will ;;; be printed. Number in A. 2dig: idivi a,10. movei c,48.(a) pushj p,tyo movei c,48.(b) jrst tyo ;;; Print out the date, whatever the fuck that means. (Noone said what ;;; the format of it is.) Anyway, the date is in 'packed form' in ;;; WHO, with year in 4.9-4.3, month in 4.2-3.8, day in 3.7-3.3, except ;;; that we have it the right half instead of the left. wdate: ldb a,[310400,,who] pushj p,2dig chrout / ldb a,[240500,,who] pushj p,2dig chrout / ldb a,[350700,,who] jrst 2dig ;;; Print out the time, in form HH:MM:SS.T. Time is in 40ths of a second, ;;; in WHO. wtim40: idivi who,4. movei a,(who) idivi a,10. push p,b ; 10ths of a second idivi a,60. push p,b ; seconds idivi a,60. push p,b ; minutes pushj p,2digt ; output the hours pop p,a pushj p,2digt ; minutes pop p,a pushj p,2dig ; seconds chrout . pop p,c addi c,48. jrst tyo 2digt: pushj p,2dig jrst tyotab+": ;;; Output the time as HH:MM:SS . Time is in WHO in 1/2 second units. wtim2: lsh who,-1 ;;; Output the time as HH:MM:SS, but time is given instead in 1-second units. wtim3: movei a,(who) idivi a,60. push p,b ; seconds idivi a,60. push p,b ; minutes pushj p,2digt pop p,a pushj p,2digt pop p,a jrst 2dig ;;; Print WHO as an octal halfword. (I presume that we ignore leading ;;; zeros...) woctal: movei f,8. movei a,(who) jrst numprt ;;; Print out WHO as a decimal halfword. (leading 0's?) wdecimal: movei f,10. movei a,(who) jrst numprt ;;; Print out WHO as a number, in the base specified by F. Supra-decimal ;;; bases won't work. numprt: idivi a,(f) push p,b skipe a pushj p,numprt pop p,c addi c,48. jrst tyo ;;; Print out the right half of WHO as 3 sixbit characters. wsix: ldb c,[140600,,who] addi c,32. pushj p,tyo ldb c,[060600,,who] addi c,32. pushj p,tyo andi who,77 movei c,32.(who) jrst tyo ;;; Here is the hairy part: Figure out what the 'job status' is. ;;; For a running job, if we can figure out how, we want to print something ;;; like WARP, MULTIX, RUN, FLY, etc. The other possibilities are ;;; STOP (the job has the tty but is totally stopped, eg while its ;;; superior is fielding a .break or some other fatal interrupt), ;;; being inside a uuo or system call, (eg NETBLK), or doing I/O to ;;; some device, eg ARCBO. There is also the potential for a leading ;;; "+" which means that the job is running in the system at that instant. ;;; The total number of characters alloted to this cruft is: ;;; 1 for the "+", 6 for device name, and 2 for io mode (all worst case), ;;; so this will be put in a fixed field of 9 characters. jobsts: skipe @ustp jrst [movei a,60./2 ? pushj p,setclk ;1/2 second for STOP movei a,[asciz | STOP |] ? jrst strt] skipn @flsins jrst chkrun move t,@uswst ; swapping status tlnn t,200000 ; Paging? (?) jrst chkrna movei a,[asciz | PAGE |] jrst strt chkrun: move t,@upc tlnn t,%pcusr jrst chkrna ;; Figure out how much run time we are getting. space move a,@jtmu ; Output the time in the form muli a,100. div a,[2.^6.] idivi a,10. ; eg, skipn a skipa c,[40] movei c,48.(a) ; "40/60%" pushj p,tyo movei c,48.(b) pushj p,tyo chrout / movei a,10000. idiv a,@sloadu pushj p,2dig .strt |% | MOVE A,@JTMU ;type out PEEK's crawl hack ADDI A,9830. ;magic numbers!! IDIVI A,19661. MOVEI B,0 CAIL A,1 MOVEI B,1 CAIL A,2 MOVEI B,2 CAIL A,10. MOVEI B,3 CAIL A,49. MOVEI B,4 CAIL A,79. MOVEI B,5 CAIL A,89. MOVEI B,6 move a,runtbl(b) pushj p,u6type ;don't type trailing spaces? jrst tyotab+40 RUNTBL: SIXBIT /MULTIX/ SIXBIT /TENEX/ SIXBIT /WALK/ SIXBIT /RUN/ SIXBIT /FLY/ SIXBIT /ZOOM/ SIXBIT /WARP/ chkrna: move t,@sv40 hlrz tt,t cain tt,(.call) jrst chkcal trz tt,(<0 17,0>) ; Clear ac field move c,@option tlnn c,%opdec jrst itsuuo caie tt,40_9 ; INIT cain tt,41_9 ; OPEN jrst rnduuo cain tt,47_9 ; CALLI jrst rnduuo itsuuo: cain tt,(.iot) jrst chkdev cain tt,(.oper) jrst chkopr cain tt,(.call) jrst chkncl move i,tt lsh i,-9 cail i, ; Huh? caml i,nuuosx rnduuo: skipa f,[sixbit |UUO|] move f,@uuosxb ; UUOSXB is indexed off of I. jrst uuosts chkcal: move f,@lscall came f,[sixbit |SIOT|] camn f,[sixbit |IOT|] jrst chksdv uuosts: pushj p,sysp move a,f pushj p,6type movei a,[asciz | |] jrst strt sysp: skipe @flsins skipa c,[" ] movei c,"+ jrst tyo chksdv: skipl tt,@uuac ; System call name in F. One of SIOT or IOT. jrst uuosts caia chkdev: ldb tt,[270400,,t] ; T has the SV40; this is a .IOT uuo. pushj p,sysp push p,tyocnt ; to do a 'charpos' calculation... addi tt,@iochnm move tt,(tt) ; get IOCHNM word contents hlrz b,tt movei i,(tt) hll tt,@iottb ; LH gets dir and blockp bits hll b,@clstb tsne b,%clsj jrst [movei i,(b) ? move e,@jbdev ? jrst chkdv1] ; Job device movei i,(tt) hllz e,@dchstb camn e,[sixbit |TTY|] ; If it is a tty, tsnn tt,%iotot ; and output, jrst chkdv1 trnn b,%tjstp ; and is hung in a **MORE**, then jrst chkdv1 .strt |**MORE**| sub p,[1,,1] popj p, chkdv1: ldb c,[360600,,e] addi c,40 pushj p,tyo lsh e,6 jumpn e,chkdv1 tsne tt,%iotbk ; block mode bit chrout B camn f,[sixbit |SIOT|] chrout S movei c,"O tsnn tt,%iotot movei c,"I pushj p,tyo pop p,e addi e,8. chkdv2: camg e,tyocnt popj p, movei c,32. pushj p,tyo jrst chkdv2 ;;; T has SV40. Opcode is for .OPER. chkopr: hrrz tt,t caml tt,mxopr jrst rnduuo movei i,(tt) move f,@oprsxb jrst uuosts chkncl: ldb i,[270400,,t] move f,@calsxb jrst uuosts truntm: ;type job's runtime as secs.xxx move a,@utrntm ;job's runtime in 4 usec units idivi a,250. ;now in msec idivi a,1000. ;sec in a, msec in b push p,b movei f,10. ;type in decimal pushj p,numprt ;type secs in a chrout . pop p,a ;recover msec idivi a,100. ;h in a, tu in b pushj p,tyotab+"0(a) move a,b jrst 2dig killme: ;clear line 25 and die .strt |y1| pushj p,output .logout 1, jclhak: ;Check jcl for any flags, options, etc. ;For now, ANY jcl at all means we turn off inverse video move a,[jclbuf,,jclbuf+1] setzm jclbuf blt a,jclbuf+ljclbuf-1 .break 12,[..rjcl,,jclbuf] skipe a,jclbuf ;skip if no jcl at all seto a, ;else set flag to true setcam a,invers ;and store the complement popj p, tsint0: push p,a hrrz a,tsint+1 ;the pc we were interrupted out of caie a,hang ;was it hanging? jrst tsintx ;nope, bye setzm (p) ;.hang will continue when we dismiss movei a,5*60. ;reset clock to 5 secs if necessary came a,clktim pushj p,setclk tsintx: pop p,a .dismis tsint+1 purif: ;don't name this PURIFY lest someone do PURIFYG movem a,sysver movem b,machine .call [setz ? sixbit |CORBLK| ? %climm,,%cbndr\%cbndw %climm,,%jself ? %climm,,200 ? %climm,,%jsnew((SETZ))] .lose %lssys move a,[2000,,<200*2000>] blt a,<200*2000>+1777 ;Copy the entire page 1 .call [setz ? sixbit |CORBLK| ? %climm,,%cbndr\%cbndw %climm,,%jself ? %climm,,1 ? %climm,,%jself %climm,,200((SETZ))] .lose %lssys .call [setz ? sixbit |CORBLK| ? %climm,,0 ? %climm,,%jself %climm,,200((SETZ))] .lose %lssys move a,[-128.,,128.] ;Map in the system setz b, .call [setz ? sixbit |CORBLK| ? movei %cbndr ? movei %jself move a ? movei 400000 ? setz b] .lose %lssys move a,[-nsyssym,,syssym] evallp: move t,(a) ;get the squoze symbol ldb b,[400400,,t] ;get the "reloc" type out of hi 4 bits .eval t, .lose add t,4ztab(b) ;add in the "reloc" movem t,1(a) ;store the evaluated and relocated symbol add a,[1,,1] ;Skip the stored value aobjn a,evallp .call [setz ? sixbit |CORBLK| ; Purify page 2, it should have movei %cbndr ; only constants and code. movei %jself setzi 1 ] jfcl ; Ok if it ain't there. skipe debug jrst purifx .value [asciz |:SL SYS3;TS H19WHOî:PDUMP DSK:SYS3;TS H19WHOî:FORGETî|] setom forgot purifx: popj p, 4ztab: 0 ;define some syms for SQUOZE 4z==4*<.-4ztab> ? 400000 4z.j==4*<.-4ztab> ? 400000(J) 4z.i==4*<.-4ztab> ? 400000(I) 4z.tty==4*<.-4ztab> ? 400000(TTY) syssym: ;;; Job variables; referenced by "@", the location VAR will have ;;; an index field of J which should be the (internal) job number. irps x,,[uname jname usysnm ustp flsins uswst jtmu utrntm nmpgs nswpgs upc sv40 option lscall uuac iochnm uwho1 uwho2 uwho3] squoze 4z.j,x x: 0 termin ;;; Symbols indexed by I. irps x,,[oprsxb uuosxb iottb clstb jbdev dchstb calsxb mxopr] squoze 4z.i,x x: 0 termin ;;; System job addresses: irps x,,[sloadu usrhi] squoze 4z,x x: 0 termin ;;; Totally random symbols: the location will hold the symbol's value. irps x,,[%clsj %iotot %iotbk nuuosx maxj lublk] squoze 0,x x: 0 termin ;;; TTY variables - reference by "@", will have an index field ;;; of TTY. irps x,,[ttyopt ttysts tctyp] squoze 4z.tty,x x: 0 termin nsyssym==.-syssym constants end go