.TITLE UTX .SBTTL INTRO PAGE ; ; UTL IS A TASK TO DISPLAY THE STRUCTURE OF THE USER TASK LIST ; ; UTL WILL DISPLAY THE RELATIVE RANKING OF TASKS ON EACH OF THE ; N LEVELS AND WILL DISPLAY FLAGS FOR: ; NEXT TASK TO SWAP ; NEXT TASK TO LOAD ; ROBIN POINTER ; ; AFTER RUNNING VIA A: ; ; MCR>UTL (TO RUN EVERY 60 CLOCK TICKS) ; OR: ; ; MCR>UTL 15 (TO RUN EVERY 15 CLOCK TICKS) ; ; ; UTL WILL DISPLAY THE UTL AND UPDATE ITSELF EVERY N TICKS ; ; A CONTROL C WHILE THE TASK IS RUNNING WILL CAUSE IT TO EXIT AFTER THE ; END OF THE NEXT DISPLAY ; ;DUE TO THE NUMBER OF VARIATIONS IN DIRECT CURSOR ADDRESSING FOR THE ;VARIOUS CRT TERMINALS, (WE'VE SEEN =, Y, * DEFINE THE ;SECOND CHARACTER OF THE ESC SEQUENCE HERE, (OR PATCH WITH A TKB GLOBAL DEF) ; ESCCHR=='= ; ; .MCALL DIR$,QIOW$,MRKT$,EXIT$S,GMCR$,WTSE$,ASTX$ .SBTTL DIRECTIVE PARAMTER BLOCKS ; ;GET MCR ; GMCR: GMCR$ ; ;QIO TO WRITE LINE ; QIO: QIOW$ IO.WVB,5,1,,IOST,, ; ;QIO FOR DIRECT CURSOR ADDRESS ; CURQIO: QIOW$ IO.WLB!IO.WAL,5,1,,,, ; ;ATTACH WITH ^C AST QIO ; ATT: QIOW$ IO.ATA,5,1,,IOST,, ; ;DETACH ; DET: QIOW$ IO.DET,5,1,,IOST,,<> ; ; ;EXIT AST'S ; ASTEXI: ASTX$ ; ;60 TICK MARK TIME (CAN BE CHANGED) ; MARK: MRKT$ 2,60.,1 ; ;WAIT FOR MARK TIME ; WAIT: WTSE$ 2 ; .SBTTL STORAGE AREA EXITFL: .WORD 0 ;FLAG FOR EXIT PENDING NLEVEL: .WORD 0 ;NUMBER OF LEVELS SPSAVE: .WORD 0 ;SAVE STACK POINTER HERE IOST: .WORD 0,0 ;IO STATUS BLOCK ; LINE: .ASCII <14>/ LEVEL 1 LEVEL 2 LEVEL 3 LEVEL 4/ .ASCII / LEVEL 5 LEVEL 6/ LINELN=.-LINE .EVEN ; CURBUF: .BLKB 200 ;LARGE BUFFER FOR CURSOR ADDRESSING CUREND: .BLKB 20 ;OVERFLOW AREA ; ; ;SAVE AREA FOR LAST DISPLAY, SAVE NUMBER OF TASKS/LEVEL ;CURRENTLY MAXIMUM OF 6 LEVELS ; DISNUM: .BLKW 6 ; ;ROOM FOR 6 LEVELS OF UTL DATA ;FOR EACH LEVEL WILL STORE ; ;0() NUMBER OF TASKS AT THIS LEVEL ;2() ROBIN POINTER ;4() NEXT JOB TO LOAD POINTER ;6() NEXT JOB TO SWAP POINTER ; BUFF: .BLKW 24. ; ; ;THE TASK WILL PUSH ON HIS STACK THE TASK NAMES OF THE VARIOUS TASKS ;IN EACH UTL LEVEL AND THE RECOVER THEM ; .SBTTL INTRO CODE START: DIR$ #GMCR ;GET MCR TO SET RECALL MOV #GMCR+6,R0 ;BUMP PAST "UTX " JSR PC,$CDTB ;GET # OF TICKS /SCAN CMP R1,#10 ;DO CHECK OF RANGE BLT 2$ ;TOO LOW, THEN BRANCH CMP R1,#300. ;EVERY 5 SECONDS IS MAX BGT 2$ MOV R1,MARK+M.KTMG ;CHANGE MARK TIME MAGNITUDE 2$: DIR$ #ATT ;ATTACH WITH AST'S MOV #.UTLHD,R0 ;GET UTL LISTHEAD CLR R1 ;CLEAR COUNTER 22$: MOV (R0),R0 ;GET NEXT/FIRST LEVEL INC R1 ;COUNT A LEVEL CMP (R0),#.UTLHD ;BACK AT UTL LISTHEAD BNE 22$ ;NO MUL #13.,R1 ;MAKE R1 SIZE OF LINE MOV R1,QIO+Q.IOPL+2 ;FILL IN LENGTH DIR$ #QIO ;WRITE HEADER LINE .SBTTL STORE UTL DATA REGO: TST EXITFL ;EXIT PENDING BEQ 1$ ;NO DIR$ #DET ;DETACH TERMINAL EXIT$S ;YES 1$: MOV SP,SPSAVE ;SAVE STACK POINTER SUB #30,SP ;MAKE ROOM FOR OUR SUB CALLS ETC MOV #BUFF,R5 ;POINT TO UTL DATA STORAGE AREA CLR NLEVEL ;CLEAR LEVEL COUNTER MOV #.UTLHD,R0 ;GET USER TASK LISTHEAD MOV (R0),R0 ;GET FIRST LEVEL STORE: MOV Z.NE(R0),(R5) ;SAVE NUMBER OF TASKS BIC #177400,(R5)+ ;CLEAR UPPER BYTE MOV Z.NT(R0),(R5)+ ;SAVE NEXT TASK TO RUN MOV Z.LD(R0),(R5)+ ;SAVE NEXT TASK TO LOAD MOV Z.NS(R0),(R5)+ ;SAVE NEXT TASK TO SWAP MOVB Z.NE(R0),R4 ;GET LOOP COUNTER BEQ 2$ ;DON'T STORE IF LEVEL EMPTY MOV Z.FJ(R0),R1 ;GET FIRST JOB NODE ADDRESS IN R1 1$: MOV X.TD(R1),R2 ;GET STD OF TASK IN R2 MOV S.TN(R2),-(SP) ;SAVE NAME MOV S.TN+2(R2),-(SP) MOV X.TI(R1),-(SP) ;SAVE TI POINTER CMP SP,#20 ;ARE WE TOO FULL ? BLT SHOW ;IF SO, DON'T SAVE ANY MORE MOV R1,-(SP) ;SAVE UTL NODE ADDRESS FOR AN ID MOV (R1),R1 ;GET NEXT JOB NODE ADDRESSS SOB R4,1$ ;DO UNTIL ALL JOBS AT THIS LEVEL FOUND 2$: INC NLEVEL ;COUNT A LEVEL MOV (R0)+,R0 ;GET NEXT LEVEL CMP R0,#.UTLHD ;BACK AT START ? BEQ SHOW ;IF SO DISPLAY BR STORE ;ELSE TRY FOR NEXT LEVEL .SBTTL SHOW TASKS SHOW: ; ;DURING THIS CODE, REGISTER USAGE IS AS FOLLOWS ; ;R0 = POINTER TO CURRENT OUTPUT BUFFER BEING ASSEMBLED ;R1 = POINTER TO LEVEL STORAGE AREA IN "BUFF:" ;R2 = ;R3 = USED TO READ SAVED DATA BACK OFF STACK ;R4 = CURRENT LEVEL (0 = FIRST LEVEL) ;R5 = CURRENT TASK AT THIS LEVEL (0 = FIRST TASK) ; MOV SPSAVE,SP ;RESET STACK TO START MOV SP,R3 ;SET R3 TO READ SAVED DATA SUB #30,R3 CLR R4 ;START AT LEVEL 0 MOV #CURBUF,R0 ;POINT R0 TO OUTPUT ASCII BUFFER MOV #BUFF,R1 ;POINT TO FIRST LEVEL IN "BUFF" DISLEV: MOV #1,R5 ;START AT FIRST TASK IN LEVEL DISTAS: CMP R5,0(R1) ;DONE WITH TASKS AT THIS LEVEL ? BGT LEVDON ;IF SO, SEE IF NEED TO DELETE SOME JSR PC,DISONE ;ELSE DISPLAY THIS TASK INC R5 ;COUNT A TASK BR DISTAS ;AND DISPLAY ANOTHER LEVDON: DEC R5 ;MAKE ACTUAL NUMBER OF TASKS FOUND MOV R4,R2 ;GET LEVEL # ASL R2 ;MAKE IT WORD OFFSET ADD #DISNUM,R2 ;POINT TO NUMBER OF TASKS LAST TIME CMP R5,(R2) ;COMPARE BEQ NODIFF ;SAME NUMBER BGT ADDSOM ;MORE THIS TIME MOV R2,-(SP) ;SAVE R2 WIPED IN ERASE CALL JSR PC,ERASE ;SOME TO ERASE MOV (SP)+,R2 ;RESTORE HIM ADDSOM: MOV R5,(R2) ;MORE TASKS, UPDATE NUMBER DISPLAYED NODIFF: ;SAME NUMBER OF TASKS AT THIS LEVEL INC R4 ;GO TO NEXT LEVEL ADD #10,R1 ;UPDATE BUFF POINTER CMP SP,#20 ;ARE WE NEARING END OF STACK ? BLT FULL ;IF SO, QUIT DISPLAYING CMP R4,NLEVEL ;CHECK NUMBER OF LEVELS DISPLAYED BLT DISLEV ;IF NOT ALL, DISPLAY ANOTHER FULL: CMP R0,#CURBUF ;ANYTHING LEFT TO OUTPUT ? BEQ NONE ;NO SUB #CURBUF,R0 ;GET SIZE MOV R0,CURQIO+Q.IOPL+2 ;AND RESET IN DPB DIR$ #CURQIO ;DO IT NONE: MOV #CURBUF,R0 ;RESET POINTER DIR$ #MARK ;WAIT ONE SECOND DIR$ #WAIT ;WAIT FOR IT JMP REGO ;AND GO AGAIN ; ;ENTRY FOR CONTROL C SEEN ; CCENT: INC EXITFL ;SHOW EXIT PENDING DIR$ #ASTEXI ;EXIT AST .SBTTL DISPLAY TASK ;ENTER WITH ;R0 = POINTER TO CURRENT ASCII OUTPUT BUFFER ;R1 = POINTER TO LEVEL STORAGE AREA IN "BUFF" ;R2 = AVAILABLE (WIPED BY $C5TA) ;R3 = POINTER TO SAVED TASK DATA ON STACK ;R4 = CURRENT LEVEL (0 = FIRST LEVEL) ;R5 = CURRENT TASK AT THIS LEVEL (1 = FIRST TASK @ LEVEL) DISONE: MOV R1,-(SP) ;SAVE R1 FOR LATER USE MOVB #33,(R0)+ ;FILL IN ESC SEQ MOVB #ESCCHR,(R0)+ ;FOR SOROC MOV R5,R1 ;GET TASK NUMBER ADD #41,R1 ;MAKE IT Y POSITION MOVB R1,(R0)+ MOV R4,R1 ;GET LEVEL # MUL #13.,R1 ;14 COLUMNS BETWEEN LEVELS ADD #40,R1 ;COLUMN 1 = 40 MOVB R1,(R0)+ MOV -(R3),R1 ;GET FIRST HALF OF TASK NAME JSR PC,$C5TA ;CONVERT TO ASCII MOV -(R3),R1 ;GET 2ND HALF OF TASK NAME JSR PC,$C5TA MOVB #40,(R0)+ ;PUT IN SPACE MOV -(R3),R1 ;GET PUD POINTER MOVB U.DN(R1),(R0)+ ;FILL IN TI NAME MOVB U.DN+1(R1),(R0)+ MOV R2,-(SP) MOV R3,-(SP) MOVB U.UN(R1),R3 ;GET UNIT NUMBER CLR R2 ;CLEAR UPPER REG DIV #10,R2 ;SEPERATE DIGITS OF DEV NUMBER BIS #60,R2 ;CONVERT UPPER DIGIT TO ASCII MOVB R2,(R0)+ BIS #60,R3 ;CONVERT REM (LOWER DIGIT) TO ASCII MOVB R3,(R0)+ MOV (SP)+,R3 ;RESTORE REG'S MOV (SP)+,R2 MOV -(R3),R2 ;GET UTL ADDRESS MOV (SP)+,R1 ;RECOVER LEVEL STORAGE AREA POINTER MOVB #40,(R0) ;PUT IN A SPACE FOR FLAG CMP R2,2(R1) ;IS IT ROBIN POINTER ? BNE 1$ MOVB #162,(R0) ;IF SO, SET FLAG 1$: CMP R2,4(R1) ;OR NEXT JOB TO SWAP ? BNE 2$ MOVB #163,(R0) ;IF SO, SET FLAG 2$: CMP R2,6(R1) ;OR NEXT JOB TO LOAD ? BNE 3$ MOVB #154,(R0) ;IF SO, SET FLAG 3$: INC R0 ;ADJUST FOR SPACE OR FLAG CHARACTER CMP R0,#CUREND ;ARE WE OVERFLOWING OUTPUT BUFFER ? BLT NOOUT ;NO SUB #CURBUF,R0 ;YES, GET SIZE MOV R0,CURQIO+Q.IOPL+2 ;SET LENGTH OF QIO DIR$ #CURQIO ;OUTPUT THE BUFFER MOV #CURBUF,R0 ;RESET OUTPUT BUFFER START NOOUT: RTS PC .SBTTL ERASE OLD TASK ; ;SUB TO ERASE TASKS AT END OF A LEVEL WHEN THE NUMBER OF TASKS AT ;THAT LEVEL DECREASES ; ;CALL WITH ; ;R5 = FIRST TASK AT LEVEL TO BE ERASED ;(R2) = NUMBER OF TASKS LAST TIME WE DISPLAYED ;R4 = CURRENT LEVEL ; ERASE: MOV (R2),R2 ;NUMBER OF TASKS LAST TIME SUB R5,R2 ;MINUS NUMBER NOW = ERASE COUNT MOV R2,-(SP) ;SAVE COUNT FOR LATER ERALOO: MOVB #33,(R0)+ ;FILL IN ESC SEQ MOVB #ESCCHR,(R0)+ ;FOR SOROC MOV R1,-(SP) MOV R5,R1 ;GET TASK NUMBER ADD #42,R1 ;MAKE IT Y POSITION (OFFSET BY 1 CAS R5 WAS ;LAST DISPLAYED TASK) MOVB R1,(R0)+ MOV R4,R1 ;GET LEVEL # MUL #13.,R1 ;14 COLUMNS BETWEEN LEVELS ADD #40,R1 ;COLUMN 1 = 40 MOVB R1,(R0)+ MOV #12.,R1 ;DO 12 SPACES 1$: MOVB #40,(R0)+ SOB R1,1$ MOV (SP)+,R1 ;RESTORE R1 INC R5 ;COUNT AN ERASE SOB R2,ERALOO ;AND DO R2 ERASES SUB (SP)+,R5 ;MAKE R5 RIGHT AGAIN CMP R0,#CUREND ;ARE WE OVERFLOWING OUTPUT BUFFER ? BLT NO ;NO SUB #CURBUF,R0 ;YES, GET SIZE MOV R0,CURQIO+Q.IOPL+2 ;SET LENGTH OF QIO DIR$ #CURQIO ;OUTPUT THE BUFFER MOV #CURBUF,R0 ;RESET OUTPUT BUFFER START NO: RTS PC ;AND RETURN .END START