;***************************************************************************; ;* *; ;* PRINTQ *; ;* Displays dynamic print queue stats for all spoolers *; ;* *; ;***************************************************************************; ; Copyright (C) 1987 ; by ; Cherokee Information Management Services ; All Rights Reserved ; Written by: Larry Laurel ; ;Edit History: ;1.0 Feb 21, 1987 created. /LPL ;1.1 Feb 26, 1987 by Dave Heyliger - AMUS : Stack problem fixed VMAJOR=1 VMINOR=1 VSUB=0 VWHO=0 SEARCH SYS SEARCH SYSSYM SEARCH TRM RADIX 16. ; The following offsets are for a queue block printer entry Q.QLINK = 00 ; Link to next queue block Q.FLINK = 04 ; Link to first file in queue Q.SPOOL = 08 ; Spooler name Q.FORMS = 0C ; Forms ID Q.REMAN = 10 ; Blocks remaining for this printer ; The following offsets are for a queue block print file entry F.FLINK = 00 ; Link to next queue block F.PFILE = 04 ; Name of print file F.DEVIC = 0A ; Device where file is located F.PPN = 0C ; PPN where file is located F.DRIVE = 0E ; Drive number where file is located F.REMAN = 18 ; Blocks remaining for this file ; Miscellaneous screen controls CLEAR = 00 ; Clear screen HOME = 01 ; Cursor to row 1, col 1 CLREOL = 09 ; Clear to end of line LOW = 0B ; Low intensity HIGH = 0C ; High intensity GRAFIX = 17 ; Turn graphics on (text off) TEXT = 18 ; Turn text on (graphics off) CURON = 1C ; Cursor on CUROFF = 1D ; Cursor off REVERS = 20 ; Start reverse video NORMAL = 21 ; End reverse video ; Special graphics characters TLCORN = 26 ; Top-left corner TRCORN = 27 ; Top-right corner BLCORN = 28 ; Bottom-left corner BRCORN = 29 ; Bottom right corner TINTER = 2A ; Top intersection RINTER = 2B ; Right intersection LINTER = 2C ; Left intersection BINTER = 2D ; Bottom intersection HLINE = 2E ; Horizontal line VLINE = 2F ; Vertical line INTER = 30 ; Intersection DEFINE TAB ROW,COL SAVE D1 MOVB ROW,D1 ROLW D1,#8 MOVB COL,D1 TCRT REST D1 ENDM DEFINE SCREEN CODE SAVE D1 MOVW #-1_8+CODE,D1 TCRT REST D1 ENDM PRINTQ: PHDR -1,PH$REE!PH$REU ; No privliges, re-entrant, re-uasble .OFINI .OFDEF SNAME,8 ; UNPACK buffer for RAD50 names .OFDEF FNAME,1A ; Output buffer for file names .OFSIZ MEMSIZ ; Allocate impure area GETIMP MEMSIZ,A5 ; Set octal, image mode and no-echo JOBIDX MOVW JOBTYP(A6),D4 ; Get the job type ANDW #^C,JOBTYP(A6) ; Set OCTAL MOV JOBTRM(A6),A6 ORW #T$IMI!T$ECS,T.STS(A6) ; Place text on the screen SCREEN CUROFF ; Turn off cursor SCREEN CLEAR ; Clear screen SCREEN LOW ; Set reduced intensity TAB #1,#19 TYPE Print Queue Status Total of ALL Queues : TAB #3,#3 TYPE Spooler Forms Remaining Current File Remaining Run TAB #4,#4 TYPE Name ID in Queue Name in File State SCREEN HIGH ; Set normal intensity ; Draw graphics border SCREEN GRAFIX ; Turn on graphics ; Place horizontal lines on screen TAB #2,#1 ; Position cursor MOV #4F,D0 ; Set up counter for 79. columns 5$: SCREEN HLINE ; Make a line SOB D0,5$ ; Loop TAB #5,#1 ; Position cursor MOV #4F,D0 ; Set up counter for 79. columns 10$: SCREEN HLINE ; Make a line SOB D0,10$ ; Loop TAB #18,#1 ; Position cursor MOV #4F,D0 ; Set up counter for 79. columns 15$: SCREEN HLINE ; Make a line SOB D0,15$ ; Loop ; Place vertical lines on screen MOV #01,D2 CALL VERTLN MOV #0B,D2 CALL VERTLN MOV #14,D2 CALL VERTLN MOV #20,D2 CALL VERTLN MOV #3B,D2 CALL VERTLN MOV #47,D2 CALL VERTLN MOV #4F,D2 CALL VERTLN BR CORNER ; Put in corners and intersections CORNER: TAB #2,#1 ; Position cursor SCREEN TLCORN ; Put in the upper left corner TAB #2,#4F ; Position cursor SCREEN TRCORN ; Put in the upper right corner TAB #18,#1 ; Position cursor SCREEN BLCORN ; Put in the lower left corner TAB #18,#4F ; Position cursor SCREEN BRCORN ; Put in the lower right corner TAB #2,#0B ; Position cursor SCREEN TINTER ; Place a top intersection TAB #2,#14 ; Position cursor SCREEN TINTER ; Place a top intersection TAB #2,#20 ; Position cursor SCREEN TINTER ; Place a top intersection TAB #2,#3B ; Position cursor SCREEN TINTER ; Place a top intersection TAB #2,#47 ; Position cursor SCREEN TINTER ; Place a top intersection TAB #5,#0B ; Position cursor SCREEN INTER ; Place an intersection TAB #5,#14 ; Position cursor SCREEN INTER ; Place an intersection TAB #5,#20 ; Position cursor SCREEN INTER ; Place an intersection TAB #5,#3B ; Position cursor SCREEN INTER ; Place an intersection TAB #5,#47 ; Position cursor SCREEN INTER ; Place an intersection TAB #18,#0B ; Position cursor SCREEN BINTER ; Place a bottom intersection TAB #18,#14 ; Position cursor SCREEN BINTER ; Place a bottom intersection TAB #18,#20 ; Position cursor SCREEN BINTER ; Place a bottom intersection TAB #18,#3B ; Position cursor SCREEN BINTER ; Place a bottom intersection TAB #18,#47 ; Position cursor SCREEN BINTER ; Place a bottom intersection TAB #5,#1 ; Position cursor SCREEN LINTER ; Place a left intersection TAB #5,#4F ; Position cursor SCREEN RINTER ; Place a right intersection SCREEN TEXT 10$: CLR D0 ; Init spooler counter CLR D3 ; Init total block count MOV LPTQUE,A0 ; Get pointer to 1st printer CMP A0,#00 ; Anybody there? JEQ DONE ; No spoolers 20$: INC D0 ; Increment spooler counter MOV D0,D2 ; Spooler counter ==> screen position ADD #5,D2 ; add offset from top of screen ; Process spooler name LEA A1,Q.SPOOL(A0) ; Address of RAD50 spooler name CALL UNPK02 TAB D2,#3 ; Position cursor TTYL SNAME(A5) ; Output name ; Process forms ID LEA A1,Q.FORMS(A0) ; Address of RAD50 forms ID CALL UNPK02 TAB D2,#0D ; Position cursor TTYL SNAME(A5) ; Output name ; Process blocks remaining for this spooler TAB D2,#17 ; Position cursor CLR D1 ; Clear the register MOVW Q.REMAN(A0),D1 ; Get the remaining block count ADDW D1,D3 ; Add it the grand total DCVT 5,OT$TRM!OT$ZER ; Output it ; Process current file and blocks remaining for that file MOV Q.FLINK(A0),A3 ; Pointer to first file entry CMP A3,#0 ; Any files in queue? JNE 30$ ; Yes - output info CALL CLRFIL ; No - Clear entries on screen JMP 40$ ; Loop ; Output the device name, file name, and PPN 30$: LEA A2,FNAME(A5) ; Point to file name buffer PUSH A2 ; Save it MOV #19,D1 ; Init counter to 25. 35$: MOVB #20,(A2)+ ; Space DEC D1 ; Decrement counter BNE 35$ ; Loop CLRB @A2 ; Null terminator LEA A1,F.DEVIC(A3) ; Address of RAD50 device name POP A2 ; Restore pointer to file name buffer UNPACK CLR D1 ; Clear the register MOVW F.DRIVE(A3),D1 ; Get the drive number DCVT 0,OT$MEM ; Move it into buffer MOVB #3A,(A2)+ ; ":" LEA A1,F.PFILE(A3) ; Address of RAD50 file name UNPACK UNPACK MOVB #2E,(A2)+ ; "." UNPACK MOVB #5B,(A2)+ ; "[" CLR D5 ; Clear the register MOVW F.PPN(A3),D5 ; PPN CLR D1 ; Clear the register MOVW D5,D1 ; Move to D1 for manipulation ASRW D1,#8 ; Get the P AND #0FF,D1 ; Mask off low order byte OCVT 0,OT$MEM ; Send it to the buffer MOVB #2C,(A2)+ ; "," CLR D1 ; Clear the register MOVB D5,D1 ; Get the PN OCVT 0,OT$MEM ; Send it to the buffer MOVB #5D,(A2)+ ; "]" TAB D2,#22 ; Position cursor TTYL FNAME(A5) ; Output name ; Process blocks remaining for this file TAB D2,#3F ; Position cursor CLR D1 ; Clear the register MOVW F.REMAN(A3),D1 ; Get the remaining block count DCVT 5,OT$TRM!OT$ZER ; Output it ; Find spooler run state and output it 40$: TAB D2,#4A ; Position cursor MOV JOBTBL,A1 ; Get address of job table 45$: MOV (A1)+,D7 ; Get next JCB address BEQ 45$ ; No job allocated - loop CMP D7,#-1 ; End of job table? ;--- Stack adjustment here (1.1) BNE 47$ ; nope PUSH ; bogus "stack adjust" JMP 65$ ; NOW go here... ;--- 47$: MOV D7,A2 ; Put that baby into an A register LEA A3,Q.SPOOL(A0) ; Get spooler name from spool queue LEA A4,JOBNAM(A2) ; Get job name from JCB CMP (A3)+,(A4)+ ; Same? BNE 45$ ; No - get next JCB CLR D1 ; Clear the register MOVW JOBSTS(A2),D1 ; Get the run state PUSH D1 ; Save it for later ANDW #J.IOW,D1 ; IO wait state? BEQ 50$ ; No - check something else TYPE IOW ; Output state JMP 65$ ; Exit 50$: POP D1 ; Restore run state PUSH D1 ; Save it for later ANDW #J.EXW,D1 ; External wait state? BEQ 55$ ; No - check something else SCREEN LOW ; Low intensity TYPE exw ; Output state SCREEN HIGH ; Restore intensity JMP 65$ ; Exit 55$: POP D1 ; Restore run state PUSH D1 ; Save it for later ANDW #J.MON,D1 ; At AMOS dot? BEQ 60$ ; No - check something else TTYI ; Output state BYTE 08 ; Backspace for reverse video BYTE 0 EVEN SCREEN REVERS ; Draw attention to this TYPE mon ; Output state SCREEN NORMAL ; Turn off reverse video JMP 65$ ; Exit 60$: POP D1 ; restore run state PUSH D1 ; Save it for later ANDW #1,D1 ; Documented as J.ALC, but undefined BNE 65$ ; Job is not in ordinary RUN state TYPE RUN ; Output state JMP 65$ ; Exit ; The JMP above is left in case we want to stick in more tests 65$: CTRLC DONE TCKI ; Check for a keystroke BNE 70$ ; None - carry on TIN ; Get the input into D1 CMPB D1,#1B ; Is it an escape? JEQ DONE ; Yes - Adios 70$: POP ; Clean up the stack MOV Q.QLINK(A0),A0 ; Get pointer to next spooler CMP A0,#00 ; Anybody there JNE 20$ ; Loop for next spooler TAB #1,#4A ; Position cursor MOV D3,D1 ; Set up to output the grand total DCVT 6,OT$TRM!OT$ZER ; Output it SLEEP #1388 ; Snooze & give up some CPU JMP 10$ ; Start over DONE: JOBIDX MOVW D4,JOBTYP(A6) ; Restore the job type SCREEN CURON SCREEN CLEAR EXIT ;***************************************************************************; ;* *; ;* Misc Subroutines *; ;* *; ;***************************************************************************; VERTLN: MOV #3,D0 ; Initial row number 5$: TAB D0,D2 ; Position cursor SCREEN VLINE ; Make a line INC D0 ; Increment row CMP D0,#18 ; End of screen? BNE 5$ ; Loop RTN UNPK01: ; Routine to unpack 1 word LEA A2,SNAME(A5) ; Address of unpacking buffer UNPACK CLRB @A2 RTN UNPK02: ; Routine to unpack 2 words LEA A2,SNAME(A5) ; Address of unpacking buffer UNPACK UNPACK CLRB @A2 RTN CLRFIL: ; Clear file entries for a spooler TAB D2,#22 ; Position cursor TTYI ASCII / / BYTE 0 EVEN TAB D2,#3F ; Position cursor TTYI ASCII / / BYTE 0 EVEN RTN END .