Google
 

Trailing-Edge - PDP-10 Archives - BB-M080K-SM - monitor-sources/diag.mac
There are 50 other files named diag.mac in the archive. Click here to see a list.
;------------------------- Autopatch Tape # 12 -------------------------
; UPD ID= 2063, SNARK:<6.1.MONITOR>DIAG.MAC.55,   3-Jun-85 14:29:03 by MCCOLLUM
;TCO 6.1.1406  - Update copyright notice.
; UPD ID= 2038, SNARK:<6.1.MONITOR>DIAG.MAC.54,   3-Jun-85 11:45:31 by TBOYLE
;TCO 6.1.1420 - Enhance DGEXRL and DGUNLK to check lock validity.
; UPD ID= 1871, SNARK:<6.1.MONITOR>DIAG.MAC.53,   4-May-85 11:21:25 by MCCOLLUM
;TCO 6.1.1238 - Fix more BUG. documentation
; UPD ID= 1816, SNARK:<6.1.MONITOR>DIAG.MAC.52,  24-Apr-85 15:26:53 by MCCOLLUM
;TCO 6.1.1238 - Fix more BUG. documentation
; UPD ID= 1786, SNARK:<6.1.MONITOR>DIAG.MAC.51,  23-Apr-85 12:46:00 by MCCOLLUM
;TCO 6.1.1238 - Fix more BUG. documentation
; UPD ID= 1724, SNARK:<6.1.MONITOR>DIAG.MAC.50,   8-Apr-85 11:04:39 by MCCOLLUM
;TCO 6.1.1238 - Fix BUG. documentation
; UPD ID= 1461, SNARK:<6.1.MONITOR>DIAG.MAC.49,   2-Feb-85 11:21:41 by GROSSMAN
;TCO 6.1.1169 - Prevent certain DIAG functions from manipulating the KLNI.
; UPD ID= 1446, SNARK:<6.1.MONITOR>DIAG.MAC.48,   1-Feb-85 13:53:27 by HAUDEL
;TCO 6.1.1168 - Set up T1 after call to CITEST in DGRLCH code.
; UPD ID= 1308, SNARK:<6.1.MONITOR>DIAG.MAC.47,  11-Jan-85 13:16:35 by GRANT
;TCO 6..1129 - In DGUDPT, check for offline.  Also, change DIAG20 to DIAG21.
; UPD ID= 1014, SNARK:<6.1.MONITOR>DIAG.MAC.46,   9-Nov-84 11:47:29 by MCLEAN
;FORCE ERROR ON DUAL PORTED DISKS FOR CHANNEL RESERVATION
; UPD ID= 4867, SNARK:<6.MONITOR>DIAG.MAC.45,  24-Sep-84 16:11:59 by GRANT
;Pass reason code to PPDRPT
; UPD ID= 4860, SNARK:<6.MONITOR>DIAG.MAC.44,  20-Sep-84 12:01:08 by GRANT
;In DGPDL, if channel is CI there must be a controller number
; UPD ID= 4643, SNARK:<6.MONITOR>DIAG.MAC.43,  31-Jul-84 16:09:17 by PURRETTA
;Update copyright notice.
; UPD ID= 4410, SNARK:<6.MONITOR>DIAG.MAC.42,   2-Jul-84 07:16:50 by GRANT
;Minor changes to routine DGENBL
; UPD ID= 4396, SNARK:<6.MONITOR>DIAG.MAC.41,  27-Jun-84 17:13:53 by GRANT
;In DGENBL, set CS.OFL
; UPD ID= 4322, SNARK:<6.MONITOR>DIAG.MAC.40,  11-Jun-84 11:05:14 by HAUDEL
;More changes to CI Maintenance Data functions.
; UPD ID= 4298, SNARK:<6.MONITOR>DIAG.MAC.39,   4-Jun-84 15:25:53 by HAUDEL
;More changes to CI Maintenance Data functions.
; UPD ID= 4151, SNARK:<6.MONITOR>DIAG.MAC.38,  30-Apr-84 13:26:30 by HAUDEL
;Make changes to CI Maintenance Data functions.
; UPD ID= 4134, SNARK:<6.MONITOR>DIAG.MAC.37,  25-Apr-84 12:03:39 by HAUDEL
;Add CI Maintenance Data functions (READ/WRITE)
; UPD ID= 3992, SNARK:<6.MONITOR>DIAG.MAC.36,  28-Mar-84 09:30:47 by HAUDEL
;In DGRLCH, do an OKSKED and IOPION if a CI channel.
; UPD ID= 3848, SNARK:<6.MONITOR>DIAG.MAC.35,   5-Mar-84 12:10:57 by GRANT
;Add functions for dumping the KLIPA
; UPD ID= 3806, SNARK:<6.MONITOR>DIAG.MAC.34,  29-Feb-84 09:47:43 by HAUDEL
;More TCO 6.1546 - Change AOBJN to AOBJP
; UPD ID= 3805, SNARK:<6.MONITOR>DIAG.MAC.33,  29-Feb-84 08:22:30 by HAUDEL
;More TCO 6.1546 - Performance Counters
; UPD ID= 3791, SNARK:<6.MONITOR>DIAG.MAC.32,  28-Feb-84 15:25:30 by HAUDEL
;More TCO 6.1546 - New KLIPA Performance counter format.
;Change calls of SC.ABF to PPDGDB.
; UPD ID= 3728, SNARK:<6.MONITOR>DIAG.MAC.31,  22-Feb-84 13:53:39 by HAUDEL
;TCO 6.1980 - Allow TGHA to get 256K for new 64K memory chips.
; UPD ID= 3692, SNARK:<6.MONITOR>DIAG.MAC.30,  15-Feb-84 14:58:23 by GRANT
;Change meaning of function 104 from controlling the "poller" to
; managing the u-code.
;Enhance function 111 to take/release the CI.
; UPD ID= 3536, SNARK:<6.MONITOR>DIAG.MAC.29,  25-Jan-84 12:33:05 by HAUDEL
;More TCO 6.1546 Performace counters
; UPD ID= 3442, SNARK:<6.MONITOR>DIAG.MAC.28,  12-Jan-84 10:15:43 by HAUDEL
;More TCO 6.1546 Performance counters
; UPD ID= 2635, SNARK:<6.MONITOR>DIAG.MAC.27,  25-Jun-83 20:44:36 by MCLEAN
;TCO 6.1705 MAKE ENABLE/DISABLE CI BE WHEEL OR OPERATOR ONLY.
; UPD ID= 2593, SNARK:<6.MONITOR>DIAG.MAC.26,  20-Jun-83 10:26:27 by HALL
;TCO 6.1689 - Move fork tables to extended section
;	Reference FKPGS and FKJOB through DEFSTR
; UPD ID= 2475, SNARK:<6.MONITOR>DIAG.MAC.25,  16-May-83 22:49:42 by MCLEAN
;TCO 6.1127 ADD ONLINE A DISK TO DIAG FOR KLIPA
;REMOVE AN EXTRANEOUS RET AT DGENB1+4
;TCO 6.1658 ADD A FEW NOINTS TO KLIPA CODE
; UPD ID= 2449, SNARK:<6.MONITOR>DIAG.MAC.24,  10-May-83 04:29:11 by WACHS
;TCO 6.1651 - Ask for KLIPA reload when that chan is released
; UPD ID= 2207, SNARK:<6.MONITOR>DIAG.MAC.23,   8-Apr-83 06:08:42 by WACHS
;MORE TCO 6.1569
; UPD ID= 2140, SNARK:<6.MONITOR>DIAG.MAC.22,   4-Apr-83 07:20:49 by WACHS
;TCO 6.1569 - Add performance counter functions
; UPD ID= 2009, SNARK:<6.MONITOR>DIAG.MAC.19,  16-Mar-83 08:35:37 by MILLER
;TCO 6.1546 yet again. Redo dispatch tables
; UPD ID= 2008, SNARK:<6.MONITOR>DIAG.MAC.18,  16-Mar-83 08:06:41 by MILLER
;Once more to get the assembly conditionals correct.
; UPD ID= 1999, SNARK:<6.MONITOR>DIAG.MAC.17,  15-Mar-83 17:01:45 by MILLER
;TCO 6.1546. Add DIAG function to read SERCNT
; UPD ID= 1893, SNARK:<6.MONITOR>DIAG.MAC.16,   1-Mar-83 15:08:45 by HALL
;TCO 6.1502 - Allow free space outside of section 0
;	At least temporarily, make all callers request section 0
; UPD ID= 1590, SNARK:<6.MONITOR>DIAG.MAC.15,  28-Dec-82 08:00:35 by WACHS
;TCO 6.1355 - Add DIAG symbols needed for CI functions
; UPD ID= 1496, SNARK:<6.MONITOR>DIAG.MAC.14,   1-Dec-82 09:55:13 by GRANT
;TCO 6.1010 - fix the immediate mode references to CSTs
; UPD ID= 875, SNARK:<6.MONITOR>DIAG.MAC.13,   8-Jun-82 23:24:50 by MURPHY
;TCO 6.1147 - Move bugdefs from BUGS.MAC to here and put them in-line.
; UPD ID= 574, SNARK:<6.MONITOR>DIAG.MAC.12,   1-Apr-82 21:24:05 by MURPHY
;TCO 6.1074 - Revise build procedures, eliminate KLPRE, etc.
; UPD ID= 506, SNARK:<6.MONITOR>DIAG.MAC.11,  16-Mar-82 08:08:35 by MILLER
; UPD ID= 503, SNARK:<6.MONITOR>DIAG.MAC.10,  15-Mar-82 18:57:10 by MILLER
; UPD ID= 480, SNARK:<6.MONITOR>DIAG.MAC.9,  13-Mar-82 19:44:46 by MILLER
;tco 6.1066 again. Add pseudo-console code
; UPD ID= 479, SNARK:<6.MONITOR>DIAG.MAC.8,  13-Mar-82 18:42:53 by MILLER
; UPD ID= 478, SNARK:<6.MONITOR>DIAG.MAC.7,  13-Mar-82 17:08:17 by MILLER
;TCO 6.1066. ADD DIAG CONSOLE JSYS FUNCTIONS
; UPD ID= 164, SNARK:<6.MONITOR>DIAG.MAC.6,  23-Oct-81 15:41:11 by COBB
; UPD ID= 160, SNARK:<6.MONITOR>DIAG.MAC.5,  23-Oct-81 15:01:24 by COBB
; UPD ID= 131, SNARK:<6.MONITOR>DIAG.MAC.4,  19-Oct-81 15:08:18 by COBB
;TCO 6.1029 - CHANGE SE1CAL TO EA.ENT
;TCO 5.1523 - SET THE CDB BACK ONLINE AT DGPDL2
; UPD ID= 69, SNARK:<6.MONITOR>DIAG.MAC.2,  15-Sep-81 16:00:34 by PAETZOLD
;TCO 6.1010 - Move CSTs to CSTSEC - change CST0 non-mask references
; UPD ID= 1943, SNARK:<5.MONITOR>DIAG.MAC.5,   6-May-81 04:03:08 by WACHS
;TCO 5.1312 - CLOSE RACE WINDOW TO PREVENT RH2PIL BUGCHKS
; UPD ID= 1732, SNARK:<5.MONITOR>DIAG.MAC.4,  19-Mar-81 08:39:34 by WACHS
;TCO 5.1273 - RETURN CCW LIST AS WELL AS CHAN LOGOUT AREA
;TCO 5.1272 - ALLOW 2 DIAG JOBS TO COEXIST BETTER
; UPD ID= 509, SNARK:<4.1.MONITOR>DIAG.MAC.32,   6-May-80 16:13:56 by DBELL
;TCO 4.1.1155 - ALLOW SKIP STYLE CCW WORDS TO BE USED
; UPD ID= 356, SNARK:<4.1.MONITOR>DIAG.MAC.31,  26-Mar-80 11:06:18 by DBELL
;TCO 4.1.1119 - MAKE CHANGES NECESSARY FOR RP20 DISKS
;TCO 4.1.1115 - ALLOW MULTIPLE CCWS TO BE USED IN .DGSCP FUNCTION
;<4.MONITOR>DIAG.MAC.30, 25-Sep-79 11:22:05, EDIT BY DBELL
;FIX TYPO IN 4.2476
;<4.MONITOR>DIAG.MAC.29, 21-Sep-79 16:29:33, EDIT BY DBELL
;TCO 4.2476 - MAKE .DGPDL FUNCTION WORK IN GENERAL, EVEN ON TXO3'S
;<OSMAN.MON>DIAG.MAC.1, 10-Sep-79 15:21:53, EDIT BY OSMAN
;TCO 4.2412 - Move definition of BUGHLTs, BUGCHKs, and BUGINFs to BUGS.MAC
;<4.MONITOR>DIAG.MAC.27,  4-Mar-79 15:03:17, EDIT BY KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<4.MONITOR>DIAG.MAC.26, 26-Feb-79 11:48:14, Edit by MCLEAN
;MAKE BLOCK TYPE CHECK FOR KDB IN DGPDL
;<4.MONITOR>DIAG.MAC.25, 22-Feb-79 12:06:29, Edit by MCLEAN
;CHANGE SE1CAL IN DGPDL TO SE1ENT
;<4.MONITOR>DIAG.MAC.24, 19-Feb-79 22:29:12, Edit by MCLEAN
;INCREMENT JB0FLG AFTER MTAJB0
;<4.MONITOR>DIAG.MAC.23, 18-Feb-79 01:21:49, Edit by MCLEAN
;FIX DGPDL TO CORRECTLY RECOGNIZE NON-EX DEVICE
;<4.MONITOR>DIAG.MAC.22, 18-Feb-79 01:08:27, Edit by MCLEAN
;FIX DGPDL TO DO CORRECT VERSION OF RESET TO CHANNEL
;<4.MONITOR>DIAG.MAC.21,  7-Feb-79 23:39:36, Edit by MCLEAN
;<4.MONITOR>DIAG.MAC.20,  7-Feb-79 18:16:20, Edit by MCLEAN
;<4.MONITOR>DIAG.MAC.19,  1-Feb-79 23:23:00, Edit by MCLEAN
;<4.MONITOR>DIAG.MAC.18,  1-Feb-79 15:39:48, Edit by MCLEAN
;CHANGE FUNCTION OF .DGPDL
;<4.MONITOR>DIAG.MAC.17, 31-Jan-79 01:07:42, Edit by MCLEAN
;MORE... DGPDL FIXES
;<4.MONITOR>DIAG.MAC.16, 28-Jan-79 21:07:56, Edit by MCLEAN
;FIX DEXIST SUBROUTINE TO DO CORRECT CHECK FOR UDB
;<4.MONITOR>DIAG.MAC.15, 28-Jan-79 16:56:10, Edit by MCLEAN
;<4.MONITOR>DIAG.MAC.14, 28-Jan-79 16:25:34, Edit by MCLEAN
;MORE .DGPDL FIXES
;<4.MONITOR>DIAG.MAC.13, 28-Jan-79 14:11:01, Edit by MCLEAN
;CHANGE DIAG11 LABEL TO DIAGZ1 SO MONSYM DOESN'T MESS THINGS UP
;<4.MONITOR>DIAG.MAC.12, 28-Jan-79 14:00:24, Edit by MCLEAN
;MORE .DGPDL CHANGES
;<4.MONITOR>DIAG.MAC.11, 28-Jan-79 13:54:59, Edit by MCLEAN
;<4.MONITOR>DIAG.MAC.10, 21-Jan-79 21:37:41, Edit by MCLEAN
;<4.MONITOR>DIAG.MAC.9, 21-Jan-79 17:56:07, Edit by MCLEAN
;ADD .DGPDL JSYS

;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY  BE  USED
;OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT  (C)  DIGITAL  EQUIPMENT  CORPORATION  1976, 1985.
;ALL RIGHTS RESERVED.


	SEARCH PROLOG,PHYPAR,SERCOD

	IFN FTKLIPA,<SEARCH SCAPAR>
	TTITLE DIAG

; CODE TO SUPPORT THE DIAG JSYS FOR THE KL10

	SUBTTL DIAG JSYS

	EXTERN TODCLK,PPDGDB
	EXTERN MAPPV,SETCST,MTRON,MTROFF,WATEPT,UNWEPT,MONCOR
HICHAN==7		;HIGHEST POSSIBLE CHANNEL


;DIAG-THIS ROUTINE IS CALLED TO PERFORM SEVERAL DIAGNOSTIC FUNCTIONS
;THE CURRENTLY IMPLEMENTED ONES DO THE FOLLOWING:
;
;	1.RESERVE A CHANNEL FOR USE BY A DIAGNOSTIC
;	2.RELEASE THE CHANNEL FROM USE
;	3.SETUP A CHANNEL PROGRAM
;	4.GET CHANNEL STATUS
;
;CALL FORMAT:
;	1/-# OF WORDS IN ARGLIST,,ARGLIST ADDRESS
;
;	DIAG
;RETURN
;	+1	;ERROR RETURN,WRONG STATE,ILLEGAL ADDRESS,BAD FORMAT
;	+2	;NORMAL RETURN
;
; ACCUMULATOR DEFINITIONS
;
;	P4= ARGUMENT LIST POINTER
;	Q1= FUNCTION CODE + FLAGS
;	Q2= DEVICE ADDRESS

.DIAG::	MCENT
	MOVX T1,SC%WHL!SC%OPR!SC%MNT ;CHECK FOR SUFFICIENT PRIVLEDGE
	TDNN T1,CAPENB		;AGAINST ENABLED CAPABILITIES
	RETERR(WHELX1)		;NOT GOOD ENOUGH
	UMOVE P4,1		;GET THE ARGUMENT LIST(#ARGUMENTS,,LIST ADDRESS)
	UMOVE Q1,(P4)		;GET FUNCTION CODE
	HRRZ T1,Q1		;GET JUST FUNCTION CODE
	CAIL T1,.DGACU		;RANGE CHECK FUNCTION CODE
	CAILE T1,.DGGCS		; ...
	JRST [	CAIL T1,.DGGEM	;no. is it in the other dispatch table?
		CAILE T1,DGFNEN	;""
		RETERR (DIAGX1)	;no. error
		SUBI Q1,.DGGEM-.DGGCS-1 ;GET INDEX INTO DISPATCH
		JRST DIAGZ1]	;GO DO IT
	AOBJN P4,DIAG1		;UPDATE COUNT FIELD AND CHECK IF LEGAL
DIGER:	RETERR (DIAGX3)		;ARGUMENT COUNT FIELD WAS TOO SMALL
DIAG1:	UMOVE Q2,(P4)		;GET DEVICE ADDRESS
	LOAD T1,DG%ADT,Q2	;GET ADDRESS TYPE
	SKIPE T1		;LEGAL?
	RETERR (DIAGX4)		;ILLEGAL TYPE CODE SPECIFIED
	LOAD P1,DG%DVC,Q2	;GET DEVICE CODE
	CAIL P1,.DGRH0		;CHECK RANGE
	CAILE P1,.DGRH7		; ...
	RETERR(DIAGX8)		;ILLEGAL
	SUBI P1,.DGRH0		;CONVERT TO INDEX
	SKIPN P1,CHNTAB(P1)	; ...
	RETERR(DIAGX8)		;NO SUCH CHANNEL
DIAGZ1:	HRRZ T4,Q1		;GET ADDRESS ONLY
	CALL @DIAGFT-1(T4)	;GO PERFORM SPECIFIC FUNCTION
	SMRETN			;SKIP RETURN TO USER

;DISPATCH TABLE FOR FUNCTIONS-FUNCTION CODE INDEX #

DIAGFT:	IFIW!DGASDV		;1 - ASSIGN CHANNEL-DEVICE MODE(TIMED)
	IFIW!DGASCU		;2 - ASSIGN CHANNEL-CONTROLLER MODE(UNTIMED)
	IFIW!DGRLCH		;3 - RELEASE THE CHANNEL
	IFIW!DGSTPG		;4 - SETUP CHANNEL PROGRAM
	IFIW!DGRLPG		;5 - RELEASE THE CHANNEL PROGRAM
	IFIW!DGGTST		;6 - GET THE CHANNEL LOGGED OUT STATUS
;WARNING! ADD FUNCTIONS HERE CAREFULLY!

;END OF CHANNEL-SPECIFIC FUNCTIONS. DEFINE NEW FORMAT FUNCTIONS

DIAGFA:	IFIW!DGMEM		;100 - GET MEMORY
	IFIW!DGMEM0		;101 - RELEASE MEMORY
	IFIW!DGPDL		;102 - DYNAMIC RECONFIGURATION OF CHANNEL
	IFIW!DGCNSL		;103 - CONSOLE FUNCTIONS
   IFN FTKLIPA,<
	IFIW!DGUCOD		;104 - KLIPA U-CODE FUNCITON
	IFIW!DGRSET		;105 - RESET REMOTE SYSTEM
	IFIW!DGSTRT		;106 - START REMOTE SYSTEM
	IFIW!COUNTR		;107 - PORT COUNTER FUNCTIONS
>
   IFE FTKLIPA,<
	IFIW!DGILGL		;104
	IFIW!DGILGL		;105
	IFIW!DGILGL		;106
	IFIW!DGILGL		;107
>
	IFIW!DGRSCT		;110 - Read SYSERR counter
	IFIW!DGENBL		;111 - ENABLE DGASCU FOR A CI PORT
	IFIW!DGSMAT		;112 - WRITE CI MAINTENANCE DATA
	IFIW!DGRMAT		;113 - READ CI MAINTENANCE DATA

;end of the table. All dispatches go before this comment (this is the
;last word in DIAG dispatches!)

DGFNEN==<.-DIAGFA>-1+.DGGEM	;Last function supported
;Common routine for unimplemented functions

DGILGL:	RETERR(DIAGX1)
;ASSIGN THE CHANNEL FOR USE BY THE CALLER
;

DGASDV:	CALL CITEST		;(P1/T1) CI CHAN?
	 RETERR (DIAG17)	;YES. CAN'T DO IT
	LDB T1,CSYTYP		;Get the channel type
	CAIN T1,.CTNI		;Is it an NI?
	 RETERR (DIAGX4)	; Yes, Invalid device type
	AOBJN P4,DGAS1		;NO, UPDATE POINTER
	RETERR (DIAGX3)		;COUNT FIELD BAD
DGAS1:	CALL DGUGET		;GET UDB FOR THIS REQUEST
	CALL DGUVAL		;VALIDATE ACCESS
	CALL DGUMAP		;CHECK FOR DUAL PORTED DISK
	CALL DGUDPT
	CALL DGLOCK		;SIEZE DIAG INTERLOCK, GO NOINT
	CALL DGEXAC		;LOCK PROGRAM AND GO NOSKED IF REQUESTED
	MOVE T1,JOBNO		;GET JOB NUMBER OF REQUESTOR
	SETONE DIAFL,(T1)	;REMEMBER HE HAS A RESOURCE
	CALL DGUASN		;SET MAINTENANCE MODE, BLOCK IF NEEDED
	CALL DGCASN		;ASSIGN CHANNEL
	UMOVE T1,(P4)		;GET TIME FIELD
	ADD T1,TODCLK		;AS OFFSET FROM CURRENT TIME
	MOVEM T1,UDBODT(P3)	;SET AS OVERDUE TIMER
DGUIOX:	MOVX T1,UIOF		;SET USER IOT IN PC
	IORM T1,-1(P)		;OF JSYS CALLER
	OKINT			;NOINT DONE IN DGLOCK
	RET

;ASSIGN CHANNEL IN CONTROLLER MODE-UNTIMED REQUEST

DGASCU:	CALL CITEST		;(P1/T1) CI CHAN?
	 TXNE T1,CS.DEN		;YES. IS IT ENABLED?
	CAIA			;OK
	RETERR (DIAG17)		;NO. LOSE
	LDB T1,CSYTYP		;Get the channel type
	CAIN T1,.CTNI		;Is it an NI?
	 RETERR (DIAGX4)	; Yes, Invalid device type
	CALL DGUMAP		;MAP NEXT INSTRUCTION ONTO ALL UDB
	CALL DGUVAL		;VALIDATE ACCESS
	CALL DGUMAP		;VALIDATE FOR DUAL PORTED DISKS
	CALL DGUDPT
	CALL DGLOCK		;SIEZE DIAG LOCK, GO NOINT
	CALL DGEXAC		;DO EXCLUSIVE ACCESS IF REQUESTED
	MOVE T1,JOBNO		;GET JOB NUMBER OF REQUESTOR
	SETONE DIAFL,(T1)	;REMEMBER HE HAS A RESOURCE
	CALL DGUMAP		;NOW ASSIGN
	 CALL DGUASN		;...
	CALL DGCASN		;ASSIGN CHANNEL
	JRST DGUIOX		;RETURN SETTING IOT USER


;HERE TO TEST IF A CI CHAN.
;ACCEPTS:	P1/ CDB
;RETURNS:	+1  IF IT IS, T1/ CDBSTS(P1)
;		+2  IF NOT

CITEST:	MOVE T1,CDBSTS(P1)
	TXNE T1,CS.CIP		;CI CHAN?
	RET			;YES
	RETSKP			;NO

;FOR EACH UNIT FOUND BY DGUMAP, SEE IF ITS STATE SHOULD PREVENT DIAG% FROM
;OWNING THE CHANNEL

DGUDPT:	MOVE T1,UDBSTS(P3)	;GET CURRENT STATUS
	MOVE T2,UDBST1(P3)	; AND AUX STATUS
	TXNE T1,US.OFS		;UNIT OFFLINE?
	RET			;YES, NO PROBLEM
	TXNN T2,U1.DCD!U1.FED	;IGNORE FRONT-END AND DON'T-CARE DISKS
	TXNN T1,US.2PT		;IS IT DUAL PORT?
	RET			;NO
	RETERR (DIAG21)		;YES, RETURN ILLEGAL
;HERE TO RELEASE A CHANNEL AND ALL DEVICES

DGRLCH::SAVEQ
	CALL DGCCHK		;VERIFY CHANNEL IN MAINTENANCE MODE
	CALL DGUMAP		;MAP ONTO ALL UDBS
	 CALL [	MOVSI T1,(US.MAI!US.MRQ) ;CHECK FOR MAINTENANCE MODE
		TDNN T1,UDBSTS(P3) ; ...
		RET		;NOT IN MAINTENANCE
		CALLRET DGUREL]	;RELEASE
	CALL DGRLPG		;RELEASE CHANNEL PROGRAM
	MOVSI T3,(CS.MAI!CS.MRQ) ;SET TO RELEASE CHANNEL
	HRRZ T2,CDBDSP(P1)	;GET CHANNEL DISPATCH
	S0.ENT			;LOWER LEVEL RUNS IN SEC0
	NOSKED
	IOPIOF
	ANDCAM T3,CDBSTS(P1)	;RELEASE CHANNEL
	HLLOS CDBONR(P1)	; ...
	SETZM CDBODT(P1)	; ...
   IFN FTKLIPA,<
	CALL CITEST		;(P1/T1) CI CHAN?
	 JRST DGRLC1		;YES
>
	LDB T1,CSYTYP		;Get the channel type
	CAIN T1,.CTNI		;KLNI?
	 JRST DGRLC1		; Yes, don't do disk stuff
	MOVEI T1,0		;DO CHANNEL ONLY RESET
	CALL CDSRST(T2)		;RESET CHANNEL PIA, ETC.
	CALL RSTSEK		;RESTART SEEKS
	CALL SCHXFR		;AND ANY TRANSFER
DGRLC1:	IOPION
	OKSKED
	SE1CAL			;BACK TO SEC1
	CALL DGEXRL		;RELEASE EXCLUSIVE ACCESS IF ACQUIRED
	MOVX T1,UIOF		;CLEAR IOT USER
	ANDCAM T1,-5(P)		;IN JSYS CALLERS PC
	CALL DGUNLK		;CLEAR DIAG LOCK
	RET
;UNLOCK ANY LOCKED PAGES.  LOCATION DIAGCW POINTS TO THE BLOCK OF RESIDENT
;STORAGE CONTAINING THE CCW WORDS.  THE FIRST WORD OF THE BLOCK IS AN
;AOBJN POINTER TO THE ACTUAL CCW WORDS.


DGRLPG:	SAVEQ			;SAVE ACCUMULATORS
	CALL DGCCHK		;CHECK CHANNEL IN MAINTENANCE MODE
	NOINT			;NO INTERRUPTIONS
	HRRZ T1,CDBICP(P1)	;GET ICCW ADDRESS FOR THIS RH20
	SETZB Q1,(T1)		;CLEAR ANY JUMP WORD AND AN AC
	EXCH Q1,DIAGCW		;ZERO STORAGE POINTER AND GET OLD ONE IF ANY
	JUMPE Q1,DGRLFN		;DONE IF NO STORAGE WAS ASSIGNED
	SKIPN Q2,0(Q1)		;GET AOBJN POINTER TO THE CCW LIST
	JRST DGRLRL		;IF NONE, JUST RELEASE STORAGE

DGRLLP:	LDB T1,[POINT 13,(Q2),26]	;GET PHYSICAL CORE PAGE FROM CCW
	SKIPE T1		;WAS THERE ONE?
	CALL MULKCR		;YES, UNLOCK THE PAGE
	AOBJN Q2,DGRLLP		;DO FOR ALL CCW WORDS

DGRLRL:	MOVE T1,Q1		;GET ADDRESS OF BLOCK WE ARE DONE WITH
	CALL RELRES		;FREE UP THE BLOCK
DGRLFN:	OKINT			;INTERRUPTS ALLOWED NOW
	RET			;DONE
;SETUP CHANNEL PROGRAM

;RH20 SPECIFIC BITS
CHJMP==1B1			;JUMP
CHXFR==1B0			;TRANSFER DATA
CHLST==1B1			;LAST TRANSFER
CHREV==1B2			;REVERSE
CCWMAX==^D50			;MAXIMUM NUMBER OF CCW'S ALLOWABLE


DGSTPG:	CALL DGCCHK		;CHECK CHANNEL IN MAINTENANCE MODE
	CALL DGRLPG		;FIRST RELEASE OLD CCW LIST
	AOBJN P4,.+2		;MAKE SURE HAVE AT LEAST ONE CCW WORD
	 RETERR (DIAGX3)	;ARGUMENT LIST WAS TOO SHORT
	HLRE T1,P4		;GET NUMBER OF CCWS TO BUILD
	MOVNS P5,T1		;CREATE POSITIVE COUNT AND SAVE IN P5
	CAILE T1,CCWMAX		;SPECIFYING TOO MANY WORDS?
	 RETERR(DIAGX6)		;YES, ILLEGAL CCW LIST
	LSH T1,1		;DOUBLE IT SO WE CAN GUARANTEE CCWS ON ONE PAGE
	HRLI T1,.RESP3		;INSERT LOWEST PRIORITY REQUEST
	MOVX T2,RS%SE0!.RESGP	;ALLOCATE FROM GENERAL POOL, SECTION 0
	NOINT			;MUST BE NOINT NOW
	CALL ASGRES		;GRAB SOME FREE CORE
	 RETERR(,<OKINT>)	;FAILED, ERROR
	MOVEM T1,DIAGCW		;REMEMBER ADDRESS OF FREE CORE BLOCK
	MOVEI T2,1(T1)		;GET POSSIBLE STORAGE ADDRESS FOR CCWS
	ANDI T2,PGSIZ-1		;KEEP ONLY OFFSET WITHIN PAGE
	ADDI T2,-1(P5)		;CREATE LAST OFFSET USED FOR CCWS
	CAIGE T2,PGSIZ		;WOULD ALL OF THE CCWS FIT ON ONE PAGE?
	TDZA T2,T2		;YES, SET UP TO USE THAT AREA
	MOVEI T2,-1(P5)		;NO, THEN USE OTHER HALF WHICH IS ON ONE PAGE
	ADDI T2,1(T1)		;CREATE ACTUAL STORAGE ADDRESS
	MOVNS P5		;NEGATE THE CCW COUNTER
	HRLZ P5,P5		;BUILD PART OF AOBJN POINTER
	HRR P5,T2		;INSERT ADDRESS WHERE CCWS ARE TO GO
	MOVEM P5,0(T1)		;SAVE POINTER TO CCWS IN FIRST WORD OF BLOCK
;NOW LOOP OVER ALL OF THE CCW WORDS SPECIFIED:


DGSTLP:	UMOVE P6,(P4)		;PICKUP NEXT CCW WORD
	 ERJMP DGSTIL		;FAILED
	JUMPGE P6,DGSTIL	;BAD CCW WORD IF NOT A TRANSFER CCW
	LDB T2,[POINT 11,P6,13]	;GET BYTE COUNT
	SOJL T2,DGST2		;ALLOW EITHER 0 OR EXACTLY ONE PAGE
	MOVE T3,P6		;COPY CCW
	ANDI T3,PGSIZ-1		;GET ADDRESS WITHIN PAGE
	TXNE P6,CHREV		;BACKWARDS?
	MOVNS T2		;YES, NEGATE COUNT
	ADD T3,T2		;DETERMINE TERMINATING WORD
	SKIPL T3		;WITHIN PAGE?
	CAIL T3,PGSIZ		; ???
	 RETERR(DIAGX7,<CALL DGRLPG
			OKINT>)	;CCW OVERFLOWS PAGE, GIVE ERROR
DGST2:	LDB T1,[POINT 18,P6,35]	;GET THE VIRTUAL ADDRESS IN AC1
	JUMPE T1,DGST3		;IF A SKIP WORD, JUST KEEP IT AS IS
	TXO T1,1B0		;INDICATE FROM USER MODE
	UMOVE T2,(T1)		;REFERENCE THE VIRTUAL PAGE TO CREATE IT
	 ERJMP DGSTIL		;FAILED
	CALL MLKMA		;LOCK THE PAGE INTO CORE
	DPB T1,[POINT 13,P6,26]	;STORE PHYSICAL PAGE INTO THE CCW
DGST3:	TXO P6,CHXFR		;FORCE TRANSFER FLAG ON
	MOVEM P6,0(P5)		;STORE FIXED UP CCW IN STORAGE BLOCK
	AOBJN P4,.+1		;ADVANCE USER'S POINTER
	AOBJN P5,DGSTLP		;LOOP FOR ALL CCW WORDS USER WANTS

	MOVX T1,CHLST		;GET FLAG READY
	IORM T1,-1(P5)		;FORCE LAST TRANSFER FLAG ON IN LAST CCW WORD
	MOVE T1,DIAGCW		;GET ADDRESS OF STORAGE BLOCK
	HRRZ T1,0(T1)		;THEN GET ADDRESS OF FIRST CCW WORD
	MAP T1,0(T1)		;FIND THE PHYSICAL ADDRESS OF THAT WORD
	TLZ T1,777760		;ZAP JUNK BITS
	TXO T1,CHJMP		;BUILD A JUMP WORD TO THE CCW LIST
	HRRZ T2,CDBICP(P1)	;GET ICCW ADDRESS
	MOVEM T1,0(T2)		;STORE THE JUMP WORD IN THE LOGOUT AREA
	SETZM 1(T2)		;CLEAR OTHER WORDS OF LOGOUT AREA
	SETZM 2(T2)		; ...
	OKINT			;INTERRUPTS OK AGAIN
	RET			;DONE


DGSTIL:	CALL DGRLPG		;RELEASE THE BLOCK
	OKINT			;ALLOW INTERRUPTS
	RETBAD(DIAGX6)		;SAY BAD CCW LIST FORMAT
;GET THE CURRENT CHANNEL STATUS FOR THE USER

DGGTST:	MOVEI T3,1(P4)		;GET USER DESTINATION
	ADD P4,BHC+3		;INCREMENT POINTER TO TEST LENGTH
	AOBJN P4,DGGT1		;UPDATE STORE POINTER
	RETERR (DIAGX3)		;POINTER WASN'T LONG ENOUGH
DGGT1:	HRRZ T2,CDBICP(P1)	;GET ICCW ADDRESS
	MOVEI T1,3		;3 WORD XFER
	CALL BLTMU		;TRANSFER WD0-WD2 TO USER SPACE
	JUMPG P4,R		;RETURN IF THATS ALL HE WANTS
	HRRZ T2,DIAGCW		;HE WANTS CCW LIST TOO - GET ITS ADDRESS
DGGT2:	MOVE T1,1(T2)		;GET A CCW
	UMOVEM T1,1(P4)		;TELL USER
	ERJMP R			;QUIT IF FAULT
	JUMPE T1,R		;RETURN AFTER STORING TERMINATING ZERO
	ADDI T2,1		;MORE - POINT AT NEXT
	AOBJN P4,DGGT2		;GIVE IT TO USER IF HE HAS THE ROOM
	RET			;FILLES ARGUMENT BLOCK - RETURN

;HERE TO DO UNIT/CONTROLLER ADDITION


DGPDL:	ADD P4,BHC+2		;CHECK SIZE TO SEE IF LEGAL
	AOBJP P4,DIGER		;NO -- TOO SMALL
	SUB P4,BHC+3		;RESTORE
	XCTU [SKIPL T1,1(P4)]	;GET CHANNEL AND CHECK VALIDITY
	CAILE T1,HICHAN		;LEGAL?
	RETERR (DIAGX8)		;NO
	SKIPE P1,CHNTAB(T1)	;MAKE SURE CHANNEL EXISTS
	XCTU [SKIPGE Q2,2(P4)]	;GET UNIT AND SEE IF NEGATIVE
	RETERR (DIAGX8)		;NO CHANNEL OR BAD UNIT
	LDB T1,CSYTYP		;Get the channel type
	CAIN T1,.CTNI		;KLNI?
	 RETERR (DIAGX4)	; Yes, this is a no no
	XCTU [SKIPL P5,3(P4)]	;CHECK FOR -1 CONTROLLER
	IFSKP.			;CONTROLLER IS LESS THAN 0
	   MOVE T2,CDBSTS(P1)	;GET CHANNEL STATUS
	   TXNE T2,CS.CIP	;IS IT A CI?
	   RETERR (DIAGX8)	;YES, MUST HAVE A CONTROLLER
	   SETO P5,		;NO, FORCE -1 CONTROLLER
	   JRST DGPDL2		;PROCEED
	ENDIF.
	HLRE T1,CDBIUN(P1)	;GET NEGATIVE NUMBER OF ENTRIES
	MOVN T1,T1		;MAKE POSITIVE
	CAML P5,T1		;VERIFY CONTROLLER NUMBER
	RETERR (DIAGX8)		;INVALID
IFN FTKLIPA,<
	MOVX T2,CS.CIP		;CHECK FOR CI PORT
	TDNN T2,CDBSTS(P1)
	JRST DGPDLA		;NO CHECK AS IF NO KLIPA HERE
	NOINT			;INHIBIT INTERRUPTS HERE
	NOSKED			;NO SCHED TOO
	IOPIOF			;AND EVERYBODY LEAVE US ALONE
	MOVE T1,P5		;GET THE NODE NUMBER
	MOVE T2,Q2		;GET UNIT NUMBER
	CALL MSCOUN		;TRY TO ONLINE UNIT
	 JRST DGPDER		;ERROR CLEAN UP
	AOS MTAJB0		;FORCE SETSPD INCASE OF TAPES
	AOS JB0FLG		;WAKE UP JOB 0
	IOPION			;INTERRUPTS BACK ON
	OKSKED			;SCHED TOO
	OKINT			;AND INTERRUPTS
	RET
DGPDER:	IOPION			;ALLOW INTERRUPTS
	OKSKED			;AND SCHEDULER
	OKINT
	RETERR ()
>		;END IFN FTKLIPA
DGPDLA:	MOVE P3,CDBIUN(P1)	;GET ADDRESS OF UDB TABLE
	ADD P3,P5		;ADD TO GET PROPER ENTRY
	SKIPN P3,(P3)		;POINTER EXIST?
	JRST DGPDL2		;NO, GO CREATE ONE
	LDB T1,USYBKT		;GET BLOCK TYPE
	CAIE T1,.BTKDB		;CHECK FOR KDB
	RETERR (DIAG12)		;ERROR DEVICE NOT ON LINE
DGPDL2:	HRRZ T1,CDBDSP(P1)	;GET DISPATCH TABLE
	CALL CDSEXT(T1)		;SEE IF UNIT ALREADY EXISTS
	SKIPA			;DOESN'T ALL OK
	JRST [	SKIPL CDBSTS(P1);DOES - IS THE CDB OFFLINE?
		RETERR (DIAG11)	;NO ILLEGAL REQUEST
		MOVSI T1,(CS.OFL) ;YES
		ANDCAM T1,CDBSTS(P1);SET IT BACK ONLINE
		RET ]		;AND DONE
	SKIPN T1		;ILLEGAL UNIT NUMBER?
	RETERR (DIAGX8)		;YES, GIVE ERROR
	PUSH P,Q2		;SAVE Q2 AND P5
	PUSH P,P5
	SKIPL P5		;CHECK FOR NO CONTROLLER
	EXCH Q2,P5		;SET Q2 TO CONTROLLER, P5 TO UNIT
	NOINT
	SE0ENT
	CALL DGUMAP		;CHECK FOR VALIDITY
	 CALL DGUVAL
	CALL DGLOCK		;LOCK
	CALL DGUMAP		;PUT IN MAI MODE
	 CALL DGUASN
	CALL DGCASN		;ASSIGN CHANNEL
	NOSKED			;NOSKED
	IOPIOF			;TURN OFF CHANNEL
	MOVE Q3,CDBIUN(P1)	;GET CORRECT UNIT ADDRESS
	ADD Q3,Q2
	CALL RH2UNS		;GO GET UNIT SETUP
	SKIPN 0(Q3)		;ALREADY EXISTS?
	MOVEM P3,0(Q3)		;NO STORE THE NEW FOUND ENTRY
	CALL DGUMAP		;RELEASE ALL THE UNITS
	 CALL [	MOVSI T1,(US.MAI!US.MRQ)
		TDNN T1,UDBSTS(P3)
		RET		;NOT IN USE FORGET IT
		CALLRET DGUREL]	;RELEASE
	MOVSI T1,(CS.MAI!CS.MRQ) ;RELEASE CHANNEL
	ANDCAM T1,CDBSTS(P1)
	HLLOS CDBONR(P1)
	HRRZ T2,CDBDSP(P1)
	MOVEI T1,0		;RESET CHANNEL
	HRRZ T2,CDBDSP(P1)	;GET CHANNEL DISPATCH
	CALL CDSRST(T2)		;RESET CHANNEL PIA,ETC.
	CALL RSTSEK		;RESTART SEEKS
	CALL SCHXFR		;AND ANY TRANSFERS
	IOPION
	SE1ENT
	OKSKED
	AOS MTAJB0		;FORCE SETSPD TO RUN INCASE MAGTAPES
	AOS JB0FLG		;START JOB 0
	CALL DGUNLK		;UNLOCK  AND RETURN
	OKINT			;ALLOW INTERRUPTS
	POP P,P5
	POP P,Q2		;RESTORE Q2
	HRRZ T1,CDBDSP(P1)	;GET DISPATCH TABLE
	CALL CDSEXT(T1)		;SEE IF UNIT NOW EXISTS
	RETERR (DIAG12)		;NO, COMPLAIN
	RET			;ALL OK
;UTILITIES

;HERE TO CHECK THAT A CHANNEL IS IN MAINTENANCE MODE

DGCCHK:	MOVSI T1,(CS.MAI)	;MAINTENANCE FLAG
	TDNN T1,CDBSTS(P1)	; ...
	RETERR(DIAGX2)		;NO - RETURN ERROR
	RET			;ALL OK

;HERE TO VALIDATE ACCESS TO A UNIT

DGUVAL:	RET			;**TEMP**
;	MOVSI T1,(US.MAL)	;MAINTENANCE MODE ALLOWED?
;	TDNN T1,UDBSTS(P3)	; ??
;	RETERR(DIAGX5)		; NO
;	RET			;YES

;HERE TO ASSIGN A CHANNEL
;ASSUMES ALL UNITS ALREADY IN MAINTENANCE MODE, THEREFORE NEVER NEEDS TO BLOCK

DGCASN:	MOVSI T1,(CS.MRQ)	;SET MAINTENANCE REQUEST BIT
	IORM T1,CDBSTS(P1)	; ...
	CALL DGUMAP		;MAP OVER ALL UNITS
	 CALL DGCAS1
	MOVSI T1,(CS.MAI)	;ALL UNITS IDLE, SET MAINT
	IORM T1,CDBSTS(P1)	; ...
	MOVSI T1,(CS.MRQ)	;CLEAR REQUEST
	ANDCAM T1,CDBSTS(P1)	; ...
	SETZM CDBODT(P1)	;CLEAR OVERDUE TIME
	HRRZ T1,FORKX		;SETUP OWNING FORK
	HRRM T1,CDBONR(P1)	; ...
	HRRZ T1,CDBICP(P1)	;AND CLEAR ICCW
	SETZM (T1)		; ...
	RET

DGCAS1:	MOVSI T1,(US.ACT!US.REW) ;UNIT IDLE?
	TDNN T1,UDBSTS(P3)	;?
	RET			;YES
	MOVS T1,P3		;NO - MUST BLOCK
	HRRI T1,DGUIDL		;WAIT FOR IDLE
	PDISMS
	JRST DGCAS1		;CHECK AGAIN
;SCHEDULER TEST ROUTINE TO WAIT FOR UNIT IDLE

DGUIDL:	MOVSI T2,(US.ACT!US.REW) ;UNIT IDLE?
	TDNE T2,UDBSTS(T1)	; ...
	JRST 0(T4)
	JRST 1(T4)		;NO - UNBLOCK
;HERE TO ASSIGN A UNIT

DGUASN:	MOVSI T1,(US.MRQ)	;SET REQUEST BIT
	IORM T1,UDBSTS(P3)	; ...
DGUAS1:	MOVSI T2,(US.ACT)	;SETUP BITS FOR PIOFF TESTS
	MOVSI T3,(US.MAI)	; ...
	NOSKED
	IOPIOF
	TDNE T2,UDBSTS(P3)	;ACTIVE?
	JRST DGUAS2		;YES - MUST BLOCK
	IORM T3,UDBSTS(P3)	;NO - SET MAINTENANCE IMMEDIATELY
	IOPION
	OKSKED
	ANDCAM T1,UDBSTS(P3)	;CLEAR MAINTENANCE REQUEST
	SETZM UDBODT(P3)	;AND OVERDUE TIMER
	HRRZ T1,FORKX		;SETUP OWNING FORK
	HRRM T2,UDBONR(P3)	; ...
	RET

DGUAS2:	IOPION			;RE-ENABLE INTERRUPTS
	OKSKED
	MOVEI T1,DGUTST		;SCHEDULER TEST ROUTINE FOR UDB BLOCK
	HRL T1,P3		;SETUP UDB
	PDISMS			;WAIT FOR BIT TO SET
	MOVSI T1,(US.MRQ)	;BIT TO CLEAR
	JRST DGUAS1		;JOIN ABOVE

;SCHEDULER TEST FOR UDB IN MAINTENANCE MODE

DGUTST:	MOVSI T2,(US.MAI)	;TEST MAINTENANCE BIT
	TDNN T2,UDBSTS(T1)	;IN UDB
	JRST 0(T4)		;NOT ON YET
	JRST 1(T4)		;ON, UNBLOCK
;HERE TO RELEASE A UNIT

DGUREL:	MOVSI T1,(US.MAI!US.MRQ)	;CLEAR MAINTENANCE BIT
	ANDCAM T1,UDBSTS(P3)	; ...
	SETZM UDBODT(P3)	;CLEAR OVERDUE TIME
	HLLOS UDBONR(P3)	;RESET OWNING FORK
	RET

;HERE TO GET THE UDB POINTED TO BY THE ADDRESS IN Q2

DGUGET:	LDB P3,[POINT 6,Q2,29]	;GET UNIT ADDRESS
	HLRE T1,CDBIUN(P1)	;WITHIN BOUNDS?
	MOVNS T1
	CAIL P3,(T1)		; ??
	RETERR(DIAGX9)		;NO
	ADDI P3,CDBUDB(P1)	;INDEX INTO UDB TABLE
	SKIPN P3,(P3)		;ANYTHING THERE?
	RETERR(DIAGX9)		;NO
	LDB T1,USYTYP		;YES - GET UNIT TYPE
	CAIE T1,.UTTM2		;KDB?
	RET			;NO - DONE
	MOVE P2,P3		;COPY
	LDB P3,[POINT 6,Q2,35]	;GET SUBUNIT NUMBER
	HLRE T1,KDBIUN(P2)	;BOUNDS CHECK
	MOVNS T1
	CAIL P3,(T1)
	RETERR(DIAGX9)		;NOT LEGAL
	ADDI P3,KDBUDB(P2)	;INDEX INTO KDB UDB TABLE
	SKIPN P3,(P3)		;UDB PRESENT?
	RETERR(DIAG10)		;NO
	RET			;YES - ALL OK
;HERE TO CHECK IF EXCLUSIVE ACCESS (LOCK AND NOSKED) IS REQUIRED
;FOR THIS DIAG REQUEST

DGEXCK:	CALL DGUMAP		;CHECK ALL UNITS ON THIS CHAN
	 CALL DGEXC1
	RET

DGEXC1:	SKIPL UDBSTR(P3)	;IS UNIT IN A STR?
	TLO Q1,(1B0)		;SET SIGN BIT - NEED EXCLUSIVE ACCESS
	RET

;HERE TO ACQUIRE EXCLUSIVE ACCESS IF REQUESTED

DGEXAC:	CALL DGEXCK		;CHECK IF EXCLUSIVE ACCESS NEEDED
	JUMPGE Q1,R		;NOT NEEDED, RETURN
DGEXCA:	SAVEP			;YES - SAVE REGISTERS
	CALL ASGPAG		;GET FREE PAGE
	RETERR(MONX02)		;INSUFFICIENT RESOURCES
	MOVE P2,T1		;COPY SCRATCH PAGE ADDRESS
	SETOM (T1)		;SET PAGE TO ALL ONES
	HRLZ T2,T1		;BUILD BLT POINTER
	HRRI T2,1(T1)		; ...
	BLT T2,PGSIZ-1(T1)	;CLEAR PAGE TO ONES
	CALL MLKMA		;LOCK IN MEMORY
	CALL DGEXNS		;DO NOSKED, SPECIAL TRAP ACTIONS
	MOVSI P1,-PGSIZ		;LOOP OVER USER ADDRESS SPACE
DGEXA1:	SKIPN UPTPGA(P1)	;USER PAGE EXIST?
	JRST DGEXA2		;NO - KEEP LOOKING
	HRRZ T1,P1		;YES - LOCK IT DOWN
	LSH T1,PGSFT		;BUILD ADDRESS
	TLO T1,(1B0)		;MARK USER ADDRESS
	CALL MLKMA		;LOCK
	MOVE T2,P2		;BUILD INDEX INTO LOCKED PAGE LIST
	ADDI T2,(P1)		; ...
	MOVEM T1,(T2)		;SAVE ADDRESS
DGEXA2:	AOBJN P1,DGEXA1		;LOOP
	HRLM P2,DIAGFK		;STORE TEMP PAGE ADDRESS TO RELEASE
	RET

;HERE TO GO NOSKED

DGEXNS:	NOSKED			;LOCK UP THE PROCESSOR
	AOS PNSKDC		;SAY HAVE A NOSKED BECAUSE OF DIAG
;******SHOULD CONSIDER TRAPPING JSYS AND TRAPS HERE
	RET			;DONE

;HERE TO RELEASE EXCLUSIVE ACCESS

DGEXRL:	MOVE T1,DIAGFK		;CHECK IF LOCK IS OWNED
	CAMN T1,[-1]		;OWNER EXISTS?
	RET			;NO - THEN NOTHING TO UNLOCK
	HLRZ T1,DIAGFK		;ANYTHING TO UNLOCK?
	JUMPE T1,R		;NO - EXIT
	SAVEP			;SAVE REGISTERS
	MOVSI P1,-PGSIZ		;SETUP TO UNLOCK ALL LOCKED PAGES
	HLRZ P2,DIAGFK		;GET TEMP PAGE ADDRESS
	SKIPN P2		;CHECK THERE WAS ONE
	BUG.(HLT,DGZTPA,DIAG,HARD,<DIAG - Locked page list page was zero>,,<

Cause:	The routine DGEXFL in the module DIAG was called to unlock any
	user pages when terminating use of the DIAG JSYS.  A pointer to
	a list of these pages should be in the left half of location
	DIAGFK. This pointer was zero.  This BUGHLT should never occur,
	since DGEXFL returns if the pointer is zero.
>)
DGEXR1:	HRRZ T1,P1		;WAS THIS PAGE LOCKED BY DIAG?
	ADD T1,P2		; ...
	SKIPGE T1,(T1)		; ?
	JRST DGEXR2		;NO - DO NOTHING
	CAML T1,MONCOR		;A REASONABLE PAGE?
	CALL MULKCR		;YES - UNLOCK IT
DGEXR2:	AOBJN P1,DGEXR1		;LOOP FOR WHOLE ADDRESS SPACE
	MOVE T1,P2		;NOW UNLOCK LOCK PAGE LIST PAGE
	CALL FPTA		;LACK OF MULKMA
	CALL MULKPG		;UNLOCK IT
	HRRZS DIAGFK		;CLEAR MEMORY OF PAGE
;****** RESTORE JSYS AND PAGE TRAP HERE
	NOINT
	SOS PNSKDC		;ONE LESS NOSKED BECAUSE OF RESOURCES
	OKSKED			;RELESE CPU
	MOVE T1,P2		;GET VIRTUAL ADDR BACK
	CALL RELPAG		;RELEASE IT
	HRRZ T1,FORKX		;CHECK IF ANY TTY ACTIVITY
	LOAD T1,FKJO%,(T1)	;GET JOB NUMBER
	HLRE T2,JOBPT(T1)	;GET CONTROLLING TERMINAL
	JUMPL T2,R		;IF DETACHED, QUIT
	CALL CKINP		;SEE IF ANY TERMINAL INPUT
	 RET			;NOTHING
	CHKINT			;USER IS TYPING. POKE SCHED
	RET
;HERE TO REQUEST THE DIAG LOCK

DGLOCK:	NOINT			;PREVENT INTS WHILE SETTING UP
	SKIPL DIAGWT		;WAIT A WHILE IF ANOTHER JOB IS BLOCKED FOR DIAG
	AOSE DIAGLK		;TEST/SET LOCK
	JRST DGLK1		;BUSY - MUST WAIT
	MOVE T1,FORKX		;HAVE LOCK - IDENTIFY OWNER
	MOVEM T1,DIAGFK		; ...
	RET

DGLK1:	OKINT			;BE OKINT WHEN BLOCKED
	SETOM DIAGWT		;INDICATE WE'RE WAITING
	MOVEI T1,DGLTST		;BLOCK
	MDISMS			; ...
	JRST DGLOCK		;TRY AGAIN

DGLTST:	SKIPL DIAGLK		;LOCK FREE?
	JRST 0(T4)		;NO
	AOSN DIAGWT		;YES, SOME OTHER FORK WAITING?
	JRST 0(T4)		;YES, LET HIM HAVE A CHANCE AT IT
	JRST 1(T4)		;MAYBE, TRY TO GET IT TOO

;HERE TO RELEASE THE DIAG LOCK

DGUNLK:	MOVE T1,DIAGFK		;CHECK FOR LOCK OWNER
	CAMN T1,[-1]		;IS LOCK OWNED?
	JRST DGUNL1		;NO, THEN NO TEMP PAGES LOCKED.
	HLRZS T1,DIAGFK		;CHECK FOR UNRELEASED TEMP PAGE
	SKIPE T1		; ...
	BUG.(HLT,DGUTPG,DIAG,HARD,<DIAG - Locked page list page locked at DIAG unlock>,,<

Cause:	The subroutine DGUNLK was called to release the interlock for the
	DIAG JSYS.  In the case that user pages were locked down, the left
	half of the location DIAGFK contains the page containing a list of
	the locked pages.  The routine DGEXFL should have been called
	previously to release this page.  However, DGUNLK found that the
	page was still assigned.
>)
DGUNL1:	SETOM DIAGFK		;INDICATE NO OWNER
	SETOM DIAGLK		;FREE LOCK
	RET
;HERE TO RELEASE ALL DIAG. RESOURCES ALLOCATED TO THIS PROCESS
;CALLED FROM KSELF IF THE FORK HAS ANY ASSIGNED

DGFKIL::HRRZ T1,DIAGFK		;THIS FORK HAVE DIAG RESOURCE NOW?
	CAME T1,FORKX		;??
	JRST FKIL3		;NO
	SAVEPQ			;SAVE ALL ACS
	MOVSI Q1,-CHNN		;BUILD AOBJN POINTER
FKIL1:	SKIPN P1,CHNTAB(Q1)	;ANYTHING PRESENT?
	JRST FKIL2		;NO - ON TO NEXT
	MOVSI T1,(CS.MRQ)	;MAINT REQUEST UP?
	TDNE T1,CDBSTS(P1)	;?
	ANDCAM T1,CDBSTS(P1)	;YES - CLEAR IT
	MOVSI T1,(CS.MAI)	;YES - IS IT IN ASSIGNED?
	TDNN T1,CDBSTS(P1)	; ??
	JRST FKIL2		;NO
	CALL DGRLCH		;YES - RELEASE IT
FKIL2:	AOBJN Q1,FKIL1		;LOOP FOR ALL CHANNELS
FKIL3:
   IFN FTKLIPA,<
	MOVSI Q1,-CHNN		;BUILD AOBJN POINTER
	MOVX Q2,CS.CIP		;CI PORT FLAG
FKIL4:	SKIPE P1,CHNTAB(Q1)	;PORT EXIST?
	TDNN Q2,CDBSTS(P1)	;YES. CI PORT?
	JRST FKIL5		;NOTHING TO DO
	HRRZ Q3,CDBCTR(P1)	;OWNER OF COUNTERS ON THIS CI PORT
	CAMN Q3,FORKX		;IS IT THIS FORK?
	HLLOS CDBCTR(P1)	;YES. RETURN THEM
FKIL5:	AOBJN Q1,FKIL4		;CHECK ALL CHANS
>
	RET			;ALL DONE
;DIAG ROUTINES FOR TGHA MEMORY CONTROL.

;MAP MEMORY. ALSO TURNS OFF PI AND ENTERS SECONDARY PROTOCOL.
;MAY ALSO TURN OFF METER

;ARGS ARE:

;	FIRST USER PAGE IN MAP REGION
;	FIRST REAL MEMORY ADDRESS TO MAP
;	COUNT OF PAGES TO MAP
;	AR/ARX TRAP ADDRESS. -1 =) NO INTERVENTION

DGMEM:	STKVAR <USRPAG,MEMPAG,CNTPAG,PAGE1,PAGE2>
	AOBJN P4,DGMEM1		;GET USER ADDRESS
	RETERR (DIAGX3)		;NOT ENOUGH ARGS
DGMEM1:	UMOVE T1,0(P4)		;GET USER PAGE ADDRESS
	SKIPL T1		;MUST BE A VALID PAGE NUMBER
	CAILE T1,777		;AND MUST BE IN ONE SECTION
	RETERR (ARGX06)		;INVALID PAGE NUMBER GIVEN
	MOVEM T1,USRPAG		;SAVE USER PAGE
	AOBJN P4,DGMEM2		;GET NEXT ARG
	RETERR (DIAGX3)		;NOT ENOUGH
DGMEM2:	UMOVE T1,0(P4)		;GET PHYSICAL ADDRESS
	CAMLE T1,NHIPG		;IS THIS PAGE EXTANT?
	RETERR(PMCLX2)		;NO. GIVE ERROR THEN
	MOVEM T1,MEMPAG		;SAVE IT
	AOBJN P4,DGMEM3		;GET LAST ARG
	RETERR (DIAGX3)		;TOO BAD. NOT THERE
DGMEM3:	UMOVE T1,0(P4)		;GET PAGE COUNT
	CAILE T1,1000		;MUST NOT BE GREATER THAN ONE SECTION
	RETERR (ARGX06)		;CAN;T HAVE IT THEN
	MOVEM T1,CNTPAG		;SAVE IT

;NOW SEE IF UPPER LIMITS MATCH

	ADD T1,MEMPAG		;GET LAST MEMORY PAGE
	SOS T1			;ONE LESS
	CAMLE T1,NHIPG		;WITHIN BOUNDS?
	RETERR (PMCLX2)		;NO. CAN;T DO IT THEN
	MOVE T1,CNTPAG		;GET COUNT AGAIN
	ADD T1,USRPAG		;GET END OF USER SPACE
	CAILE T1,1000		;WITHIN SECTION 0
	RETERR (ARGX06)		;NO. BOMB THEN
	SETOM P3		;ASSUME NO AR/ARX INTERVENTION
	AOBJP P4,DGMEM6		;IS ONE SPECIFIED?
	UMOVE P3,0(P4)		;YES. GET IT
	; ..
;HERE WITH ALL ARGS VALIDATED. NOW SET UP USER MAP

DGMEM6:	CALL DGLOCK		;GET DIAG LOCK. NOW NOINT
	MOVE T1,USRPAG		;GET USER PAGE
	MOVE T2,CNTPAG		;GET COUNT
DGMEM4:	SKIPE UPTPGA(T1)	;IS THIS MAP SLOT EMPTY?
	RETERR (ARGX06,<CALL DGUNLK>) ;NO. CAN'T DO FUNCTION THEN
	SOJLE T2,DGMEM5		;MORE TO DO?
	AOJA T1,DGMEM4		;YES
DGMEM5:	CALL ASGPAG		;GET A PAGE
	RETERR (MONX02,<CALL DGUNLK>) ;NONE THERE
	SKIP 0(T1)		;CREATE THE PAGE
	MOVEM T1,PAGE1		;SAVE THE PAGE
	CALL ASGPAG		;GET ANOTHER PAGE
	RETERR (MONX02,<CALL DGUNLK
			MOVE T1,PAGE1
			CALL RELPAG>) ;FREE THE PAGE
	MOVE T2,PAGE1		;GET ADDRESS OF PAGE 1
	MOVEM T2,0(T1)		;SAVE IT
	MOVE T2,MEMPAG		;GET FIRST MEM PAGE
	MOVEM T2,2(T1)		;SAVE IT
	MOVE T2,USRPAG		;GET FIRST USER PAGE
	MOVEM T2,3(T1)		;SAVE IT
	MOVE T2,CNTPAG		;GET COUNT OF PAGES
	MOVEM T2,4(T1)		;SAVE IT
	MOVEM T1,PAGE2
	MOVE T2,CASHF		;CURRENT CACHE STATE
	MOVEM T2,5(T1)		;SAVE IT

;USER MAP IS AVAILABLE FOR OPERATION. FIRST LOCK THE DIAGNOSTIC
;IN MEMORY

	CALL DGEXCA		;LOCK THE DIAGNOSTIC. WILL BE NOSKED ON RETURN
	MOVE T1,PAGE1		;GET PAGE I.D.
	CALL MLKMA		;LOCK IT IN
	MOVE T1,PAGE2
	HLRZ T2,DIAGFK		;SAVE LOCK PAGE
	HRLM T1,DIAGFK		;REMEMBER THIS ADDRESS
	MOVEM T2,1(T1)		;SAVE LOCK PAGE ADDRESS
	CALL MLKMA		;LOCK THIS ONE ALSO
	MOVE T1,FORKX		;GET FORK NUMBER OF THIS PROCESS
	LOAD T1,FKUP%,(T1)	;GET SPTN OF UPTA
	HRLZS T1		;PUT IN LEFT HALF ** ASSUMES HALFWORD VALUE
	HRR T1,USRPAG		;GET STARTING PAGE NUMBER
	MOVE T2,MEMPAG		;GET MEMORY PAGE
	MOVE T3,CNTPAG		;GET COUNT
	CALL MAPPV		;SET UP THE MAP

;USER MAP NOW SET UP. NEED TO FIX UP CST0 AREA

	PIOFF			;TURN OFF INTERRUPTS
	CALL CASHOF		;TURN OFF THE CACHE
   REPEAT 0,<			;SKIP THIS FOR NOW
	JSR BUGMON		;AND ENTER SECONDARY PROTOCOL
	MOVEI T1,[SIXBIT '$MOS MEMORY DIAGNOSTIC RUNNING...$/']
	JSR BUGMSG		;TELL OPERATOR
   >				;END OF REPEAT 0
	; ..
;HERE WITH MACHINE COMPLETELY UNDER THIS PROCESS'S CONTROL.
;MUST NOW TURN OFF METER, SAVE CST0 FOR TARGET PAGES
;AND MAKE TARGET PAGES ACCESSIBLE.

	CALL MTROFF		;TURN OFF CLOCK. (DISABLES
				;METER AND TIMER).

;NOW SAVE RELEVANT CST0 LOCATIONS

	MOVE T1,MEMPAG		;FIRST MEM PAGE
	XMOVEI T2,@CST0X+T1	;SOURCE
	MOVE T3,PAGE1		;DESTINATION
	MOVE T1,CNTPAG		;# OF PAGES
	CALL XBLTA		;SAVE CST0

;CST0 LOCATIONS NOW SAVED. SET UP CURRENT CST0 SO IS ACCESSIBLE

	MOVE T1,MEMPAG		;FIRST MEM PAGE
	MOVE T2,CNTPAG		;# OF PAGES
	CALL SETCST		;SET CST0 FOR THE PAGES
				;SETS AGE TO CURRENT AGE. SETS
				;USE FIELD TO ALL 1'S

;NOW ALL IS READY FOR THE DIAGNOSTIC. LET IT HAVE IT
;FIRST, WAIT FOR EPT USERS TO FINISH

	CALL WATEPT		;LET APRSRV DO THE WAITING

	MOVEM P3,DIAGAR		;SET AR/ARX INTERCEPT
	RET			;GO!
;MEMORY FUNCTION TO RELEASE ALL RESOURCES.
;NO ARS

DGMEM0:	STKVAR <USRPAG,MEMPAG,CNTPAG,PAGE1,PAGE2>
	SETZM DIAGAR		;CLEAR AR/ARX INTERCEPT
	CALL UNWEPT		;TURN ON EPT DEVICES
	HLRZ T1,DIAGFK		;GET PAGE WITH CONTROL INFO
	MOVEM T1,PAGE2		;SAVE IT
	MOVE T2,2(T1)		;FIRST MEMORY PAGE
	MOVEM T2,MEMPAG
	MOVE T3,3(T1)		;GET USER PAGE AFFECTED
	MOVEM T3,USRPAG
	MOVE T3,4(T1)		;GET COUNT OF PAGES USED
	MOVEM T3,CNTPAG
	MOVE T4,0(T1)		;GET PAGE WHERE CST0'S ARE SAVED
	MOVEM T4,PAGE1
	MOVE T1,CNTPAG		;# PAGES
	MOVE T3,T2		;GET
	ADD T3,CST0X		; DESTINATION
	MOVE T2,T4		;SOURCE
	CALL XBLTA		;RESTORE CST0 ENTRIES
	MOVE T1,PAGE2		;RESTORE CONTROL INFO PAGE
	CALL MONCLA		;CLEAR MAP
	MOVE T4,1(T1)		;GET USER LOCK PAGE PAGE
	HRLM T4,DIAGFK		;RESTORE IT
	SKIPE 5(T1)		;WANT CACHE ON?
	CALL CASHON		;YES. SO TURN IT ON
   REPEAT 0,<			;NOT NEEDED PRESENTLY
	MOVEI T1,[SIXBIT '$MOS MEMORY DIAGNOSITIC COMPLETED$/']
	JSR BUGMSG		;TELL OPERATOR
	JSR BUGPRI		;TURN ON PRIMARY PROTOCOL
   >				;END OF REPEAT 0
	PION			;AND TURN ON INTS

;SYSTEM NOW ON

	NOINT			;PREVENT INTS
	CALL DGEXRL		;UNLOCK USER. NOW OKSKED
	MOVE T1,PAGE1		;GET JSB PAGE
	CALL FPTA		;GET I.D.
	CALL MULKPG		;UNLOCK IT
	MOVE T1,PAGE1		;GET IT AGAIN
	CALL RELPAG		;RELEASE IT
	MOVE T1,PAGE2		;GET OTHER JSB PAGE
	CALL FPTA		;GET I.D.
	CALL MULKPG		;UNLOCK IT
	MOVE T1,PAGE2		;GET IT AGAIN
	CALL RELPAG		;RELEASE IT
	; ..
;NOW CLEAN UP USER MAP

	MOVE T3,CNTPAG		;# OF PAGES
	SETOM T2		;SAY CLEAR MAP
	MOVE T1,FORKX		;THIS FORK
	LOAD T1,FKUP%,(T1)	;GET SPTN OF UPTA
	HRLZS T1		;PUT IN LEFT HALF ** ASSUMES HALFWORD VALUE
	HRR T1,USRPAG		;THE STARTING PAGE NUMBER
	CALL MAPPV		;CLEAR MAP
	CALL DGUNLK		;RELEASE DIAG LOCK
	OKINT			;ALLOW INTS NOW
	RET			;AND DONE, AT LAST
;Action routine to read the value of the SYSERR counter
;The counter is a montonically increasing value of the number of
;SPEAR messages enqueue since the start-up of the monitor.

DGRSCT:	AOBJN P4,DGRSC0		;Check to make sure there's a spot for it
	RETERR (DIAGX3)		;There isn't
DGRSC0:	MOVE T1,SERCNT		;Get counter
	UMOVEM T1,0(P4)		;Stash it
	RET			;And done
IFN FTKLIPA,<
;Code for CI u-code management
;ACCEPTS:	P1/ CBD
;RETURNS:	+1 FAILED.  T1/ ERROR CODE
;		+2 SUCCESS

DGUCOD:	AOBJP P4,DIGER		;CHECK NO. OF ARGS
	SKIPN P1,CHNTAB+KLPRH2	;HAVE A KLIPA?
	RETERR (DIAG14)		;NO
	UMOVE T1,(P4)		;YES, GET SUB-FUNCTION
	CAIL T1,0		;LEGAL
	CAILE T1,DGUMAX		; SUB-FUNCTION?
	RETERR (DIAGX1)		;NO
	CALLRET @DGUDSP(T1)	;GO DO THE WORK

DGUDSP:	IFIW!DGURIP		;RELOAD-IN-PROGRESS
	IFIW!DGURLC		;RELOAD-COMPLETE
	IFIW!DGUDIP		;DUMP-IN-PROGRESS
	IFIW!DGUDMC		;DUMP-COMPLETE
DGUMAX=.-DGUDSP-1

;U-CODE RELOAD-IN-PROGRESS
;ACCEPTS:	P1/ CDB
;RETURNS:	+1

DGURIP:	CALL KLPRIP		;(P1) TELL KLIPA DRIVER
	RET


;U-CODE RELOAD-COMPLETE
;ACCEPTS:	P1/ CDB
;RETURNS:	+1

DGURLC:	CALL KLPRLC		;(P1) TELL KLIPA DRIVER
	RET


;U-CODE DUMP-IN-PROGRESS
;ACCEPTS:	P1/ CDB
;RETURNS:	+1

DGUDIP:	CALL KLPDIP		;(P1) TELL KLIPA DRIVER
	RET


;U-CODE DUMP-COMPLETE
;ACCEPTS:	P1/ CDB
;RETURNS:	+1

DGUDMC:	CALL KLPDMC		;(P1) TELL KLIPA DRIVER
	RET
;RESET REMOTE SYSTEM
DGRSET:	TDZA	Q3,Q3		;FLAG A RESET

;START REMOTE SYSTEM
DGSTRT:	MOVEI	Q3,-1		;FLAG START
	AOBJP	P4,DIGER	;CHECK NO OF ARGS
	CALL PBLESS		;BLESS THE REQUEST
	  RETERR (DIAG14)	;CHANNEL NOT THERE
	NOINT			;PREVENT INTERRUPTS
	CALL PPDGDB		;GET DATAGRAM BUFFER
	  RETERR (DIAG13,<OKINT>)	;NOT AVAILABLE
	UMOVE Q1,(P4)		;GET CHAN,,NODE AGAIN
	AOBJP P4,CALSRS		;DO THE SEND IF NO NEXT ARG
	UMOVE T3,0(P4)		;GET ARGUMENT (START - START ADDR; RESET - FORCE)
	HRL Q3,T3		;IN LH(Q3)
CALSRS:	CALL PPDSRS		;CALL THE PORT DRIVER TO DO THE SEND
	OKINT			;TURN INTERRUPTS BACK ON
	RET			;AND RETURN

;ROUTINE TO BLESS THE CALL
;CALL	P4/ADDR OF USER'S ARG
;RETURNS +1 CDB DOESN'T EXIST OR NOT A CI PORT
;RETURNS +2 P1/CDB
;	    Q1/USER'S ARG
PBLESS:	UMOVE Q1,(P4)		;CHAN,,NODE
	HLRZ T1,Q1		;CHAN
	CAIL T1,0		;LEGAL
	CAILE T1,HICHAN		; CHANNEL?
	RET			;NO
	MOVX T2,CS.CIP		;YES
	SKIPE P1,CHNTAB(T1)	;CDB EXIST?
	TDNN T2,CDBSTS(P1)	;YES. CI PORT?
	RET			;NO. LOSE
	RETSKP			;WIN
;PORT COUNTER FUNCTIONS
COUNTR:	AOBJP P4,DIGER		;CHECK NO OF ARGS
	CALL PBLESS		;BLESS THE ARGUMENT
	  RETERR(DIAG14)	;NO GOOD
	HRRZS Q1		;ISOLATE SUBFUNCTION
	CAILE Q1,CNTFLN		;LEGAL?
	RETERR(DIAGX1)		;NO
	MOVE T1,FORKX		;YES. SET T1=FORK NUMBER
	HRRE T2,CDBCTR(P1)	;AND T2=FORK WHICH CURRENTLY OWNS COUNTERS
	CALLRET @CNTFCN(Q1)	;AND DISPATCH

CNTFCN:	IFIW!CNTGET		;0 - GET COUNTERS
	IFIW!CNTGIV		;1 - RELEASE COUNTERS
	IFIW!CNTPNT		;2 - POINT COUNTERS
	IFIW!CNTRED		;3 - READ COUNTERS
CNTFLN==.-CNTFCN-1

;GET CONTROL OF THE COUNTERS
CNTGET:	CAIN T1,T2		;IS FORK ALREADY THE OWNER?
	RET			;YES.
	SKIPLE T2		;NO. IS THERE AN OWNER?
	RETERR(DIAG15)		;YES.
	HRRM T1,CDBCTR(P1)	;NO. THIS FORK NOW OWNS THEM
	RET			;GO AWAY HAPPY

;RELINQUISH CONTROL OF THE COUNTERS
CNTGIV:	CAMN T1,T2		;IS THIS FORK THE OWNER?
	JRST CNTGI1		;YES. GO RELEASE CONTROL.
	AOBJP P4,DIGER		;NO. GET THE FORCE ARGUMENT.
	UMOVE T1,(P4)
	SKIPG T1		;FORCE THE RELEASE?
	RETERR(DIAG16)		;NO.
CNTGI1:	HLLOS CDBCTR(P1)	;YES. RELEASE THEM
	RET			;AND RETURN

;POINT THE COUNTERS AT A PARTICULAR NODE
CNTPNT:	AOBJP P4,DIGER		;CHECK NO OF ARGS
	CAME T1,T2		;THIS FORK THE OWNER?
	RETERR(DIAG16)		;NO. ERROR
	NOINT			;DISABLE INTERRUPTS
	UMOVE Q1,(P4)		;YES. GET MASK ARGUMENT
	CALL PPDGDB		;GET DATAGRAM BUFFER
	 RETERR (DIAG13,<OKINT>) ;FAILED
	AOBJP P4,DIGER		;CHECK NO OF ARGS
	UMOVE Q3,(P4)		;GET NODE ARGUMENT
	MOVSI T1,1		;BUMP THE MONOTONIC NUMBER
	ADDM T1,CDBCTR(P1)	; SO READERS WILL KNOW THEY'VE RESET
	CALL PPDSPT		;(Q1,Q2,P1) TELL PORT DRIVER TO SET THE COUNTERS
	OKINT			;ALLOW INTERUPTS
	RET
;READ THE COUNTERS
;
;IN ORDER TO PERFORM A READ, THE READ LOCK (CNTLCK) MUST BE FREE (-1). IF
;IT IS NOT, THE FORK WILL WAIT UNTIL IT IS. ONCE THE FORK HAS THE LOCK,
;IT SENDS A READ FUNCTION TO THE KLIPA AND ALSO SETS A TIMER (CNTTIM). IF
;THE READ IS NOT FINISHED IN THE ALLOTED TIME,THE LOCK IS FREED AND AN
;ERROR IS RETURNED. ON THE READ, PHYKLP WILL STORE THE TIME OF THE
;READ AND THE DATA IN CNTBUF AND THEN, SET THE READ DONE FLAG (CNTFLG). THE DIAG
;CODE TESTS CNTFLG AND CNTTIM TO DETERMINE WHEN THE READ HAS EITHER FINISHED
;OR TIMED OUT.IF THE READ FINISHES, THE DATA IS COPIED TO THE 
;ARGUMENT BLOCK OF THE DIAG% AND THEN THE READ LOCK (CNTLCK) IS FREED
;AND THE READ DONE FLAG (CNTFLG) IS RESET.
;
;
CNTRED:	AOBJP	P4,DIGER	;COUNT AN ARGUMENT
CNTRD0:	AOSE CNTLCK		;IS THE COUNTER READ FUNCTION FREE?
	JRST CNTWT2		;NO. GO WAIT
	NOINT			;YES.
	CALL PPDGDB		;GET DATAGRAM BUFFER
	  JRST [SETOM CNTLCK	;FAILED TO GET BUFFER. FREE LOCK.
		OKINT
		RETERR (DIAG13)]	;AND RETURN ERROR.
	MOVE T1,TODCLK		;GET THE TIME
	ADDI T1,^D5000		;CREATE THE OVERDUE TIME
	MOVEM T1,CNTTIM		;SAVE THE OVERDUE TIME
	MOVEI T2,KS%DIA		;GET REASON CODE
	CALL PPDRPT		;(T2,Q2) TELL THE DRIVER TO READ THE COUNTERS
	CALL CNTRWT		;BLOCK TILL IT FINISHES
	  JRST CNTRDF		;READ TIMED OUT
	MOVE T1,CDBCTR(P1)	;GET RESET COUNTER AND FORK OWNER
	UMOVEM T1,(P4)		;TELL USER
	AOBJP P4,CNTRD2
	HLRE T1,P4		;NUMBER OF VALUES HE WANTS
	CAIGE T1,-.PKPDD	;TOO MANY?
	HRLI P4,-.PKPDD		;YES. DECREASE THE REQUEST
	MOVEI T1,1		;SET UP TO READ CNTBUF
	SKIPA
CNTRD1:	AOBJP P4,CNTRD2
	MOVE T3,CNTBUF(T1)	;GET A VALUE.(CNTBUF+0 IS TIME OF READ)
	UMOVEM T3,(P4)		;SAVE FOR USER
	AOJA T1,CNTRD1		;LOOP FOR NEXT
CNTRD2:	SETOM CNTFLG		;FINISHED. NOW RESET THE READ DONE FLAG.
	SETOM CNTLCK		;RESET THE LOCK.
	OKINT			
	RET

;ROUTINE TO WAIT FOR THE COUNTER READ TO FINISH

CNTRWT:	MOVEI T1,CNTRTS		;BLOCK
	MDISMS
	SKIPL CNTFLG		;DID READ FINISH?
	RETSKP			;YES.
	RET			;NO. TIMED OUT.
CNTRTS:	SKIPL CNTFLG		;HAVE COUNTERS BEEN READ?
	JRST 1(T4)		;YES.
	MOVE T1,TODCLK		;NO. CHECK OVERDUE TIME.
	CAMG T1,CNTTIM		;PAST OVERDUE TIME?
	JRST 0(T4)		;NO. WAIT SOME MORE
	JRST 1(T4)		;YES. FINISH WAIT

;ROUTINE TO WAIT FOR THE COUNTER LOCK

CNTWT2:	MOVEI T1,CNTWT3
	MDISMS
	JRST CNTRD0
CNTWT3:	SKIPL CNTLCK		;IS LOCK FREE?
	JRST 0(T4)		;NO. WAIT SOME MORE
	JRST 1(T4)		;YES.

CNTRDF:	BUG. (INF,CNTOUT,DIAG,HARD,<Read of performance counter timed out>,,<

Cause:	The KLIPA did not respond to a read of the performance counters 
	in the allotted time.
>)
		SETOM CNTFLG	;RESET THE READ DONE FLAG.
		SETOM CNTLCK	;RESET THE COUNTER READ LOCK
		OKINT
		RETERR (DIAG21)		;TIMED OUT.RETURN ERROR.

>	;END IFN FTKLIPA
;Enable DGASCU for a CI port

DGENBL:	MOVX T1,SC%WHL!SC%OPR	;MUST BE WHEEL OR OPERATOR
	TDNN T1,CAPENB		;AGAINST ENABLED CAPABILITIES
	RETERR(WHELX1)		;NOT ENOUGH
	AOBJP P4,DIGER		;POINT AT CHAN WORD
	UMOVE T1,(P4)		;GET CHAN
	SKIPL T1		;MAKE SURE ITS LEGAL
	CAILE T1,HICHAN
	RETERR(DIAG14)		;NOPE
	SKIPN P1,CHNTAB(T1)	;OK. GET CHNTAB ENTRY
	RETERR (DIAG14)		;NOTHING THERE
	MOVE T2,CDBSTS(P1)	;GET STATUS WORD
	TXNN T2,CS.CIP		;CI CHAN?
	RETERR(DIAG14)		;NOPE
	AOBJP P4,DIGER		;POINT TO ENABLE/DISABLE WORD
	UMOVE T3,(P4)		;GET IT
	SKIPE T3		;TRYING TO ENABLE DGASCU?
	IFSKP.

;Enabling DGASCU for the CI

	  MOVX T1,CS.DEN!CS.MAI!CS.OFL	;YES, SET ENABLE-DGASCU,
	  IORM T1,CDBSTS(P1)	; MAINTENANCE, AND OFF-LINE
	  CALL KLPEAC		;(P1) TELL KLIPA DRIVER
	ELSE.

;Disabling DGASCU for the CI

	  TXNE T2,CS.MRQ	;TRYING TO DISABLE IT. DIAG HAVE CHAN?
	  RETERR (DIAG20)	;YES. CAN'T DO SO
	  CALL KLPDAC		;(P1) TELL KLIPA DRIVER TO START PORT
	  MOVX T1,CS.DEN!CS.MAI!CS.OFL	;CLEAR ENABLE-DGASCU, OFFLINE,
	  ANDCAM T1,CDBSTS(P1)	; AND MAINTENANCE
	ENDIF.
	RET
;DGRMAT - ROUTINE TO REQUEST(READ) MAINTENANCE DATA OF A REMOTE NODE.
; P4/ Argument list pointer
;	CALL DGRMAT	;Called via DIAG% dispatch table
;RETURN +1: Always


DGRMAT:	STKVAR <RWFLAG,RTDG>	;RWFLAG  0 = READ MAINT. FUNCTION
				;RTDG - ADDRESS OF ROUTINE TO RETURN
				;	DATAGRAM BUFFER
	SETZM RWFLAG
	JRST DGSMA1

;DGSMAT - ROUTINE TO SEND(WRITE) MAINTENANCE DATA TO A REMOTE NODE.
; P4/ Argument list pointer
;	CALL DGSMAT	;Called via DIAG% dispatch table
;RETURN +1: Always

DGSMAT:	STKVAR <RWFLAG,RTDG>	;RWFLAG -1 = WRITE MAINT. FUNCTION
				;RTDG - ADDRESS OF ROUTINE TO RETURN DATAGRAM
				;	BUFFER.
	SETOM T1,RWFLAG

DGSMA1:				;COMMON CODE FOR MAINTENANCE DATA (READ/WRITE).
				;AC USAGE IS:
				;Q1/ CHANNEL,,NODE NO
				;Q2/ LOCKED PAGE ADDRESS
				;Q3/ BUFFER NAME
				;P2/ # OF 8 BIT BYTES
				;P3/ ADDRESS TO WRITE/READ
				;P4/ JSYS ARGUMENT LIST POINTER
				;P5/ USER ADDRESS OF DATA TO BE WRITTEN
				;    OR ADDRESS TO PLACE DATA THAT HAS
				;    BEEN READ.

				;BEGIN BY CHECKING VARIOUS CI INFORMATION
	AOBJP P4,DIGER		;ADJUST ARGUMENT LIST POINTER
	CALL PBLESS		;(P4/P1,Q1)IS IT A CI CHANNEL?
	 RETERR (DIAG14)	;NO.
				;PBLESS PUTS CHANNEL ADDRESS IN P1 AND
				;CHANNEL NUMBER,,NODE NUMBER IN Q1.
	MOVE P3,Q1		;SAVE Q1
	HRRZ Q1,Q1		;YES. GET NODE NUMBER.
	CAIL Q1,0		;LEGAL NODE NUMBER?
	CAIL Q1,C%SBLL		;MAYBE. LEGAL NODE NUMBER?
	RETERR (DIAG22)		;NO.
	XMOVEI T1,CDBUDB(P1)	;YES. GET START OF SB ADDRESSES.
	ADD T1,Q1		;ADD IN THE NODE NUMBER.
	SKIPN P2,(T1)		;IS THERE AN SB?
	RETERR (DIAG23)		;NO.
	MOVE T1,.SBDPF(P2)	;YES. GET NODE'S FUNCTIONALITY.
	;..
	SKIPN RWFLAG		;READ OR WRITE?
	IFSKP.
	  TXNN T1,PKSMD		;WRITE. DOES IT SUPPORT A MAINT. DATA WRITE?
	  RETERR (DIAG24)	;NO.
	ELSE.
	  TXNN T1,PKRMD		;READ. DOES IT SUPPORT A MAINT. DATA READ?
	  RETERR (DIAG24)	;NO.
	ENDIF.
	LOAD T1,SBDPS,(P2)	;YES. GET THE PORT STATE.
	CAIE T1,PS.UMS		;IS IT IN UNINITIALIZED MAINTENANCE MODE?
	RETERR (DIAG25)		;NO.
	LOAD T1,SBDRP,(P2)	;YES. GET RESETTING NODE NUMBER.
	MOVE T2,CDBNOD(P1)	;GET OUR NODE NUMBER.
	CAME T1,T2		;ARE THEY THE SAME?
	RETERR (DIAG25)		;NO. ERROR.
	MOVE Q1,P3		;RESTORE Q1

				;NOW CHECK THE USER'S ARGUMENTS.
	AOBJP P4,DIGER		;ADJUST THE ARGUMENT LIST POINTER.
	UMOVE P2,(P4)		;GET NUMBER OF 8 BIT BYTES TO WRITE/READ
	ERJMP [RETERR (ARGX10)]	;RETURN ERROR
	CAILE P2,0		;MUST BE GREATER THAN ZERO
	CAILE P2,^D512		;AND LESS THAN 513.
	RETERR (DIAG26)		;IT IS NOT

	AOBJP P4,DIGER
	UMOVE P3,(P4)		;GET ADDRESS OF DATA TO BE WRITTEN/READ
	ERJMP [RETERR (ARGX10)]	;RETURN ERROR

	AOBJP P4,DIGER
	UMOVE P5,(P4)		;GET USER BUFFER (WRITE/READ)
	ERJMP [RETERR (ARGX10)]	;RETURN ERROR
	
				;AT THIS POINT THE CI INFORMATION AND USER 
				;ARGUMENTS LOOK GOOD. NOW START THE REAL WORK.
	CALL DGLOCK		;() GET THE DIAG LOCK AND THIS GOES NOINT
				;ALSO AOSE DIAGLK AND DIAGFK/ 0,,FORK N0.
	MOVEI T1,1		;GET ONE BUFFER
	CALL SC.ALD		;(T1/T1,T2,T3) GET A BUFFER
	 JRST [HRLM T1,MAIFLG	;ERROR. SAVE THE ERROR CODE
		JRST FIN3]	;GO CLEAN UP LOCK
	MOVE Q2,T1		;SAVE ADDRESS
	MOVEM T3,RTDG		;SAVE ROUTINE TO DEASSIGN THE BUFFER.
				;Q2 NOW HAS ADDRESS OF BUFFER
	MAP T2,(Q2)		;GET PHYSICAL ADDRESS
	TLZ T2,777760		;GET JUST THE ADDRESS
	;..

				;NOW SET UP THE BUFFER DESCRIPTOR FOR MAPBUF
				;THE FIRST FEW LOCATIONS OF THE DATAGRAM 
				;BUFFER ARE USED FOR THE BUFFER DESCRIPTOR.
				;THE REST OF THE DATAGRAM BUFFER IS USED FOR
				;THE DMA TRANSFER.
	SETZM .MDNXT(Q2)	;GET ONLY ONE BSD
	MOVX T1,MD%DIC		;GET IND COM MODE BITS
	STOR T1,MD%DMD,.MDFLG(Q2)	;STORE IN BUFFER DESCRIPTOR BLOCK
	SKIPE RWFLAG		;READ OR WRITE?
	IFSKP.
	  MOVX T1,SQ%WRT	;READING, ALLOW KLIPA TO WRITE HOST MEMORY
	  IORM T1,.MDFLG(Q2)	;SET THE WRITEABLE BIT
	ENDIF.
	MOVE T1,P2		;GET SIZE (8 BIT BYTES)
	MOVEM T1,.MDSSD+.MDLEN(Q2)	;STORE IN BUFFER DESCRIPTOR BLOCK
	XMOVEI T1,.MDSSD+.MDLSD+1(T2)	;GET ADDRESS OF SEGMENT
	MOVEM T1,.MDSSD+.MDADR(Q2)	;STORE IN BUFFER DESCRIPTOR BLOCK
	SETZM .MDSSD+.MDLSD(Q2)	;ZERO LAST WORD OF BUFFER DESCRIPTOR

	BLCAL. (MAPBUF,<Q2>)	;/(T1) SET THE BHD AND BSD; GET BUFFER NAME
	  JRST [HRLM T1,MAIFLG	;SAVE THE ERROR CODE.
		JRST FIN2]	;CLEAN UP IF ERROR
	MOVE Q3,T1		;SAVE BUFFER NAME
	SKIPN RWFLAG		;WRITE OR A READ?
	IFSKP.
	  MOVE T1,P2		;WRITE. GET NUMBER OF BYTES TO TRANSFER
	  TRZE T1,3		;NEED TO ROUND UP
	  ADDI T1,4		;YES.
	  LSH T1,-2		;NUMBER OF WORDS TO BLT(4 BYTES PER WORD)
	  MOVE T2,P5		;GET SOURCE ADDRESS
	  XCTU [SKIP (T2)]	;IS USER ADDRESS VALID?
	  ERJMP ADDER0	;NO. GO CLEAN UP 
	  ADD T2,T1		;GET ENDING USER ADDRESS
	  XCTU [SKIP (T2)]	;IS USER ADDRESS VALID?
	  ERJMP ADDER0	;NO. GO CLEAN UP
	  MOVE T2,P5		;GET SOURCE ADDRESS AGAIN
	  XMOVEI T3,.MDSSD+.MDLSD+1(Q2)	;GET DESTINATION
	  CALL BLTUM		;(T1,T2,T3/)BLT USER DATA TO MONITOR SPACE
	ENDIF.

	
	MOVE T1,TODCLK		;GET THE TIME
	ADD T1,MAIOTC		;SET THE OVERDUE TIME
	MOVEM T1,MAITIM		;SET THE OVERDUE TIMER
	SETOM MAIFLG		;SET THE FLAG. -1 MEANS NOT COMPLETED.
				;0 MEANS COMLETED.
				;1 MEAND COMPLETED WITH ERROR.

	LSH P3,4		;PUT BITS IN POSITION THAT SNDMAI/REQMAI NEEDS.
	;..
	SKIPN RWFLAG		;READ OR WRITE?
	IFSKP.
				;BLCAL (SNDMAI,<SEND NAME,REC NAME,SEND OFFSET,
				;	  RECEIVE OFFSET,NODE AND CHANNEL>)

	  BLCAL. (SNDMAI,<Q3,P3,[0],[0],Q1>) 	;WRITE.
	   JRST [HRLM T1,MAIFLG	;SAVE THE ERROR CODE.
		  JRST FIN1]	;ERROR ONLY IF UNABLE TO GET A BUFFER
	ELSE.
				;BLCAL (REQMAI,<SEND NAME,REC NAME,SEND OFFSET,
				;	  RECEIVE OFFSET,NODE AND CHANNEL>)

	  BLCAL. (REQMAI,<P3,Q3,[0],[0],Q1>)	;READ.
	   JRST [HRLM T1,MAIFLG	;SAVE THE ERROR CODE
		  JRST FIN1]		;ERROR ONLY IF UNABLE TO GET A BUFFER
	ENDIF.

	CALL MAIRWT		;() GO WAIT FOR THE WRITE TO FINISH
	 JRST [SKIPG MAIFLG		;TIMED OUT OR FINISHED WITH ERROR?
		MOVEI T1,DIAG27		;TIMED OUT.
		MOVEI T1,DIAG30		;FINISHED WITH ERROR.
		HRLM T1,MAIFLG		;SAVE ERROR CODE.
		JRST .+1]		;CONTINUE ON.

	SKIPE RWFLAG		;WRITE OR A READ?
	IFSKP.
				;READ. TRY TO TRANSER DATA TO USER, EVEN
				;IF THERE IS AN ERROR.
	  MOVE T1,P2		;GET NUMBER OF BYTES TO TRANSFER.
	  TRZE T1,3		;NEED TO ROUND UP
	  ADDI T1,4		;YES.
	  LSH T1,-2		;NUMBER OF WORDS TO BLT(4 BYTES PER WORD)
	  XMOVEI T2,.MDSSD+.MDLSD+1(Q2)	;GET SOURCE ADDRESS
	  MOVE T3,P5		;GET DESTINATION
	  XCTU [SETMM (T3)]	;IS USER SPACE STARTING ADDRESS VALID
	  ERJMP ADDER1	;NO.
	  ADD T3,T1		;GET USER SPACE ENDING ADDRESS
	  XCTU [SETMM (T3)]	;IS USER SPACE ENDING ADDRESS VALID?
	  ERJMP ADDER1	;NO.
	  MOVE T3,P5		;GET DESTINATION AGAIN
	  CALL BLTMU		;(T1,T2,T3/) BLT  DATA TO USER SPACE
	ENDIF.
	JRST FIN0		;GO AND CLEAN UP

ADDER0:	MOVEI T1,ARGX10		;INVALID ADDRESS FOR BLTUM
	HRLM T1,MAIFLG		;SAVE ERROR CODE
	JRST FIN1		;GO CLEAN UP

ADDER1:	MOVEI T1,ARGX10		;INVALID ADDRESS FOR BLTMU
	HRLM T1,MAIFLG		;SAVE ERROR CODE
	JRST FIN0		;GO CLEAN UP
	;..
				;CLEAN UP
FIN0:	CALL MAICLO		;(Q3,P1/) CLOSE BUFFER
FIN1:	BLCAL. (UMAP,<Q3>)	;CLEAN UP THE BHD AND BSD. Q3 HAS BUFFER NAME.
	 JRST [HRLM T1,MAIFLG	;SAVE THE ERROR
		JRST FIN2]

				;CLEAN UP AFTER SUCCESSFUL TRANSFER OR
				;AFTER AN UNSUCCESSFUL TRANSFER.

FIN2:	MOVE T1,Q2		;GET THE BUFFER TO RELEASE
	MOVE T2,RTDG		;GET ROUTINE TO RELEASE BUFFER
	CALL (T2)		;(T1/) GO RELEASE THE BUFFER.
	SKIPE MAIFLG		;DID MAINT. OP COMPLETE SUCCESSFUL?
	IFSKP.
	  SETZM MAIFLG		;YES.
	  CALL DGUNLK		;() UNLOCK THE DIAG LOCK
	  OKINT
	  RET
	ENDIF.
FIN3:	MOVE Q1,MAIFLG		;SAVE THE ERROR CODE
	CALL DGUNLK		;() UNLOCK THE DIAG LOCK
	OKINT
	HLRZ T1,Q1		;GET THE ERROR CODE
	RETERR ()

	ENDSV.
	ENDSV.
;MAIRWT - SCHEDULER TEST FOR THE CI MAINTENANCE DATA FUNCTIONS
;	CALL MAIRWT
;RETURN +1: ERROR, EITHER TIMED OUT OR MUTILPLE MCNFS
;RETURN +2: FUNCTION HAS COMPLETED

;MAITIM WILL HAVE THE OVERDUE TIME. MAIFLG WILL BE A FLAG WORD.
;WHEN THE MCNF IS RECEIVED, MAIFLG WILL BE INCREMENTED.
;IF PHYKLP GETS A MCNF WHILE MAITIM IS ZERO, IT WILL
;BE TREATED AS A SPURIOUS INTERUPT, BUT IT COULD ALSO BE A LATE MAINT.
;DATA OPERATION.

;FOR THE TIMING FUNCTION MAIFLG WILL HAVE THE FOLLOWING MEANINGS
; -1 THE INITIAL VALUE AND IMPLIES THAT THE MAINTENANCE DATA OPERATION
;    HAS NOT COMPLETED
;  0 MAIFLG IS SET TO ZERO ON SUCCESSFUL COMPLETION.
;  1 OPERATION HAS COMPLETED BUT AN ERROR HAS BEEN DETECTED. ERROR
;     IS INDICATED IN THE STATUS FIELD OF THE RETURNED COMMAND PACKET.
;FOLLOWING THE TIMING FUNCTION,MAIFLG MAY LOOK LIKE
;  ERROR CODE,,X  THE ERROR CODE ON VARIOUS FAILURES WILL
;    BE STORED IN THE LEFT HALF. THE RIGHT HALF IS INDETERMINATE.
;  0,,X   IN WHICH CASE X NUMBER OF MCNFS WERE RECEIVED.

MAIRWT:	MOVEI T1,MAIRTS		;GET WAIT ROUTINE
	MDISMS			;WAIT
	SETZM MAITIM		;INDICATE THAT NO MCNFS ARE NOW EXPECTED.
	SKIPE MAIFLG		;0 IMPLIES READ HAS FINISHED.
	RET			;DID NOT COMPLETE. PROBABLY TIMED OUT.
	RETSKP			;MAINT. OPERATION COMPLETED

;MAIRTS - ACTUAL SCHEDULER TEST INVOKED BY MDISMS FROM MAIRWT.

MAIRTS:	SKIPL MAIFLG		;MAINT. OPERATION COMPLETED?
	JRST 1(T4)		;YES.
	MOVE T1,TODCLK		;NO. CHECK OVERDUE TIMER.
	CAMG T1,MAITIM		;OVERDUE?
	JRST 0(T4)		;NO. WAIT SOME MORE
	JRST 1(T4)		;YES. 
	
;MAICLO - ROUTINE TO TELL KLIPA TO CLOSE THE BUFFER SO THAT THE KLIPA WILL
;DELETE THE OPERATION FROM ITS  QUEUES.
;	CALL MAICLO
;RETURN +1:	ALWAYS


MAICLO:	SAVEQ
MAICL1:	CALL PPDGDB		;(P1/Q1) GET BUFFER FOR CLOSE BUFFER FUNCTION
	 JRST CLOERR		;FAILED. GO WAIT A BIT BEFORE TRYING AGAIN.
	MOVE T1,Q3		;GET BUFFER NAME
	MOVE Q3,CDBPCB(P1)	;GET PCB ADDRESS
	SETZM MAICLF		;ZERO THE FLAG. GT 0 = COMPLETE.
	MOVEM T1,MAICLN		;SAVE THE BUFFER NAME FOR THE WAIT ROUTINE.
	BLCAL. (CLOBUF,<T1,Q2,Q3>)	;CLOSE THE BUFFER. T1= BUFFER NAME
				;Q1= NODE NUMBER,Q2=BUFFER ADDRESS,Q3=PCB
	 JFCL 0			;CLOBUF RETURNS +2 ALWAYS
	MOVE T1,TODCLK		;GET THE TIME
	ADD T1,MACLOT		;SET THE OVERDUE TIME.
	MOVEM T1,MAICLT		;STORE THE OVERDUE TIME
	CALL MAIWA1		;() WAIT FOR THE CLOSE BUFFER OP TO COMPLETE.
	 BUG. (INF,MACBTO,DIAG,HARD,<DIAG - Close buffer timed out>,,<

Cause:	The DIAG close buffer operation has timed out before completion.
>)
	RET			;EITHER TIMED OUT OR SUCCESSFUL.

CLOERR:	MOVE T1,TODCLK		;FAILED TO GET A BUFFER , WAIT A BIT.
	ANDI T1,377777
	ADDI T1,^D200		
	HRL T1,T1
	HRRI T1,BLOCKW
	HDISMS (200)		;GO WAIT FOR 200 MS.
	JRST MAICL1		;TRY FOR A BUFFER AGAIN
;MAIWA1 - SCHEDULER TEST SET UP TO WAIT FOR THE CLOSE BUFFER (205) OPERATION.
;	CALL MAIWA1
;RETURN +1:	TIMED OUT
;RETURN +2:	COMPLETED CLOSE BUFFER OPERATION

;MAICLF IS THE FLAG TO INDICATE THAT THE OPERATION COMPLETED. MAICLN IS
;THE BUFFER NAME FOR THIS MAINTENANCE OPERATION. THIS NAME IS USED BY THE
;INTERRUPT ROUTINE SPECIFICALLY FOR THIS DIAG%.
;MAICLT HAS THE OVERDUE TIME FOR THIS OPERATION.

MAIWA1:	MOVEI T1,MAIWAT		;GET WAIT ROUTINE
	MDISMS			;WAIT
	SKIPN MAICLF		;TIMED OUT OR COMPLETED?
	RET			;TIMED OUT.
	RETSKP			;COMPLETED.

;MAIWAT - SCHEDULER TEST ROUTINE FOR THE CLOSE BUFFER (205) OPERATION.

MAIWAT:	SKIPE MAICLF		;MAINT. CLOSE BUFFER OPERATION COMPLETED?
	JRST 1(T4)		;YES.
	MOVE T1,TODCLK		;GET THE TIME
	CAMG T1,MAICLT		;PAST THE OVERDUE TIME?
	JRST 0(T4)		;NO. WAIT SOME MORE.
	JRST 1(T4)		;YES.
;Code for console special funtions. Available only on the 2080.

	SWAPCD
DGCNSL:
   IFN KLFLG,<RET>		;NO CODE FOR THIS
   IFN KCFLG,<			;LOTS FOR THIS

;The first word of the block is the subfunction. Get it and dispatch

	AOBJP P4,DIGER		;GET SUBFUNCTION
	UMOVE T1,0(P4)		;GET IT
	SKIPL T1
	CAILE T1,LSFCN-CNFCN-1	;CHECK FOR VALID FUNCION
	RETERR(DIAGX1)		;NO. ERROR THEN
	CALLRET @CNFCN(T1)	;DO THE FUNCTION

;Dispatch table for console functions

CNFCN:	IFIW!SRPCMD		;DO PSEUDO-COMMAND
	IFIW!GETEMM		;GET EMM DATA
	IFIW!NBEMM		;ENABLE/DISABLE FOR EMM INTS
	IFIW!WRTEMM		;WRITE AN EMM LINE
	IFIW!SETDXX		;SET DNxx LINE
LSFCN:
;Action routines for functions

;Send/receive pseudo-command

SRPCMD:	STKVAR <<CMDSTR,^D26>,<REPSTR,^D103>,REPCNT>
	AOBJP P4,DIGER		;IF NO COMMAND, ERROR
	MOVE T1,P4		;SAVE POINTER TO COMMAND STRING
	SETZM REPCNT		;ASSUME NO REPLY
	AOBJP P4,NORET		;IF NOT, GO ON
	UMOVE T2,0(P4)		;GET COUNT OF REPLY STRING
	MOVEM T2,REPCNT		;SAVE IT
	AOBJP P4,DIGER		;GET REPLY STRING

;Here to copy command string

NORET:	MOVE T2,[POINT 7,CMDSTR]
	MOVEI T3,^D128		;MAX STRING SIZE
	DO.
	 XCTBUU [ILDB T4,0(T1)]	;GET NEXT BYTE
	 JUMPE T4,ENDLP.	;IF AT THE END, DONE
	 IDPB T4,T2		;STASH IT
	 SOJG T3,TOP.		;DO THEM ALL
	ENDDO.
	SETZM T4		;GET A NULL
	IDPB T4,T2		;MAKE SURE TIED OFF
	SUBI T3,^D128		;COMPUTE BYTES STORED
	JUMPE T3,R		;IF NONE, NOTHING TO DO
	MOVNS T3		;GET PROPER SIGN
	MOVEI T1,CMDSTR		;GET ADDRESS OF SOURCE
	MOVEI T2,REPSTR		;REPLY
	TXO T1,<POINT 7,0>
	TXO T2,<POINT 7,0>	;MAKE STRING POINTERS
	MOVE T3,REPCNT
	BLCAL. (CDSCMD,<T1,T2,T3>) ;SEND IT TO THE CONSOLE

;Here with the reply. Send it back if requested

	MOVEI T2,REPSTR		;POINT TO START OF STRING
	TXO T2,<POINT 7,0>
	SKIPE T3,REPCNT		;ANY BYTES?
	CAMN T1,T2		;ANY BYTE SENT BACK?
	RET			;NO
	DO.
	 ILDB T4,T2		;GET A BYTE
	 XCTBUU [IDPB T4,0(P4)]	;STORE IT
	 SOJLE T3,R		;IF STRING FULL, RETURN
	 CAMN T2,T1		;AT THE END YET?
	 RET
	 LOOP.			;NO
	ENDDO.
;More action routines for console

;Read EMM data

GETEMM:	STKVAR <<EMBLK,4>>	;GET A BLOCK
	XMOVEI T1,EMBLK		;GET BLOCK ADDRESS
	CALL RDEMMS		;GET EMM DATA
	AOBJP P4,DIGER		;GET COUNT OF WORDS WANTED
	MOVEI T2,EMBLK		;GET BLOCK
	HRLI T2,-4		;MAX NUMBER TO DO
	DO.			;MOVE DATA
	 MOVE T3,0(T2)		;GET SOME
	 UMOVEM T3,0(P4)	;STASH IT
	 AOBJP P4,ENDLP.
	 AOBJN T2,TOP.
	ENDDO.
	RET			;AND DONE

;Enable/disable for EMM interrupt

NBEMM:	AOBJP P4,DIGER		;BETTER BE AN ARG
	UMOVE T2,0(P4)		;ARG
	CAILE T2,^D36		;LEGAL PSI?
	RETERR(ARGX01)		;NO
	MOVE T1,FORKX		;THIS FORK
	CALLRET ENBEMM		;DO ENABLE

;Write EMM line

WRTEMM:	AOBJP P4,DIGER
	UMOVE T1,0(P4)		;GET EMM NUMBER
	AOBJP P4,DIGER
	UMOVE T2,0(P4)		;GET VALUE TO WRITE
	BLCAL. (CNSEMM,<T1,T2>)
	RET			;AND DONE

;Set DNxx line

SETDXX:	RET			;NOT HERE YET

   >	;IFN KCFLG

	RS CNTRLK		;FLAG FOR READING PERFORMANCE COUNTER
	TNXEND
	END