;***************************************************************************;
;* *;
;* 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 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<J.HEX>,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
; 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