Google
 

Trailing-Edge - PDP-10 Archives - BB-P363B-SM_1985 - mcb/loaders/c11dmc.mac
There are no other files named c11dmc.mac in the archive.
	.TITLE	CHKDEF - SPECIFY THE HARDWARE THAT CHK11 WILL TEST
	.IDENT	/X3.05/
								.REPT 0
                                                        :                
                                          :             :         :     
                                                        :         :     
 ::::    ::::   : :::   :   :   :: ::    ::      ::: :  ::::    :::::   
:    :  :    :   :   :  :   :    ::  :    :     :   :   :   :     :     
:       :    :   :   :  :   :    :        :     :   :   :   :     :     
:       :    :   :   :  :   :    :        :     :   :   :   :     :     
:    :  :    :   ::::    ::::    :        :      ::::   :   :     :  :  
 ::::    ::::    :          :   :::      :::        :   :   :      ::   
                 :      :   :                   :   :                   
                ::       :::                     :::                    
 
				and
	
    ::                                                                
    :    :                   ::             :                         
    :                         :                                       
 ::::   ::     :::    :::     :     :::    ::   : :: ::     :::   :: ::  
:   :    :    :      :   :    :        :    :    :  :  :   :   :   ::  : 
:   :    :     :::   :        :     ::::    :    :  :  :   :::::   :     
:   :    :        :  :        :    :   :    :    :  :  :   :       :     
:   :    :    :   :  :   :    :    :   :    :    :  :  :   :   :   :     
 ::: :  :::    :::    :::    :::    ::: :  :::   :  :  :    :::   :::    
 
 
		    COPYRIGHT (C) 1980,1981,1982 BY
		DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
	
THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
ONLY  IN  ACORDANCE  WITH  THE  TERMS  OF  SUCH  LICENSE AND WITH THE
INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE  OR ANY OTHER
COPIES THEREOF MAY NOT BE PROVIDED OR  OTHERWISE MADE AVAIABLE TO ANY
OTHER PERSON.  NO TITLE  TO  AND OWNERSHIP OF THIS SOFTWARE IS HEREBY
TRANSFERRED.
T
THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE  WITHOUT NOTICE
AND  SHOULD  NOT  BE  CONSTRUED AS A COMMITMENT  BY DIGITAL EQUIPMENT
CORPORATION.
C
DIGITAL ASSUMES NO RESPONSIBILITY  FOR THE  USE OR RELIABILITY OF ITS
SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
								.ENDR
.PAGE
								.REPT 0
	.TITLE	CHKDEF - SPECIFY THE HARDWARE THAT CHK11 WILL TEST
                                                        :                
                                          :             :         :     
                                                        :         :     
 ::::    ::::   : :::   :   :   :: ::    ::      ::: :  ::::    :::::   
:    :  :    :   :   :  :   :    ::  :    :     :   :   :   :     :     
:       :    :   :   :  :   :    :        :     :   :   :   :     :     
:       :    :   :   :  :   :    :        :     :   :   :   :     :     
:    :  :    :   ::::    ::::    :        :      ::::   :   :     :  :  
 ::::    ::::    :          :   :::      :::        :   :   :      ::   
                 :      :   :                   :   :                   
                ::       :::                     :::                    
 
				and
	
    ::                                                                
    :    :                   ::             :                         
    :                         :                                       
 ::::   ::     :::    :::     :     :::    ::   : :: ::     :::   :: ::  
:   :    :    :      :   :    :        :    :    :  :  :   :   :   ::  : 
:   :    :     :::   :        :     ::::    :    :  :  :   :::::   :     
:   :    :        :  :        :    :   :    :    :  :  :   :       :     
:   :    :    :   :  :   :    :    :   :    :    :  :  :   :   :   :     
 ::: :  :::    :::    :::    :::    ::: :  :::   :  :  :    :::   :::    
 
 
		    COPYRIGHT (C) 1979,1980,1981,1982 BY
		DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
	
THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
ONLY  IN  ACORDANCE  WITH  THE  TERMS  OF  SUCH  LICENSE AND WITH THE
INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE  OR ANY OTHER
COPIES THEREOF MAY NOT BE PROVIDED OR  OTHERWISE MADE AVAIABLE TO ANY
OTHER PERSON.  NO TITLE  TO  AND OWNERSHIP OF THIS SOFTWARE IS HEREBY
TRANSFERRED.
T
THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE  WITHOUT NOTICE
AND  SHOULD  NOT  BE  CONSTRUED AS A COMMITMENT  BY DIGITAL EQUIPMENT
CORPORATION.
C
DIGITAL ASSUMES NO RESPONSIBILITY  FOR THE  USE OR RELIABILITY OF ITS
SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
								.ENDR
.PAGE
;**********************************************************************;
;								       ;
;		EDIT HISTORY AND VERSION DOCUMENTATION		       ;
;		(ALSO SEE VERSION INFO IN CHK11 BODY)		       ;
;								       ;
;  THIS MODULE IS A COMBINED TERTIARY LOADER AND HARDWARE CHECKING     ;
;  PROGRAM.  IT IS LOADED BY A SECONDARY LOADER, AND GIVEN CONTROL     ;
;  AT THE TOP.  THE "CHECK11" HARDWARE EXERCISER IS THEN INVOKED,      ;
;  AFTER WHICH THE LOADER LOADS THE SPECIFIED OPERATING SYSTEM.	       ;
;								       ;
;  "TERBOT" AND "CHK11" WERE DEVELOPED SEPERATELY.  THIS EDIT HISTORY  ;
;  BEGINS WITH VERSION 2A.0, THE FIRST TO COMBINE THE MODULES.  ONLY   ;
;  EDITS WHICH CHANGE THE SENSE OF THE CODE ARE DOCUMENTED HERE; TYPO  ;
;  CORRECTIONS AND SUCH CHANGE THE EDIT NUMBER BUT THE CHANGES ARE NOT ;
;  FLAGGED.							       ;
;								       ;
;**********************************************************************;
;								       ;
;  EDIT HISTORY:						       ;
;	X2A.00	10-NOV-78  L. WEBBER				       ;
;			ORIGINAL COMBINATION OF TERBOT AND CHK11       ;
;			(CORRESPONDS TO DTE CHK11 VERSION 2A.05)       ;
;	   .01	7-DEC-78  L. WEBBER				       ;
;			INTEGRATE CHK11 UPDATES FROM DTE VERSION       ;
;			(CORRESPONDS TO DTE CHK11 VERSION 2A.11)       ;
;	   .02	7-DEC-78  L. WEBBER				       ;
;			SKIP DEVICE DIAGNOSTICS FOR LOAD DEVICE	       ;
;			(NOT RELEVANT TO DTE CHK11)		       ;
;	   .03	8-DEC-78  L. WEBBER				       ;
;			SAVE AND RESTORE PAGE 6 MAPPING REGISTERS FOR  ;
;			MEMORY MANAGEMENT TEST			       ;
;			(NOT RELEVANT TO DTE CHK11)		       ;
;	   .04  20-DEC-78  L. WEBBER				       ;
;			MOVE DMC INITIALIZATION CODE OUT OF RELOCATED  ;
;			CODE SO THAT IT IS DONE BEFORE CHK11 STARTS;   ;
;			FIX CALL TO DMC DRIVER IN CHK11 TO RESTORE THE ;
;			SP BEFORE INVOKING IT.			       ;
;			(NOT RELEVANT TO DTE CHK11)		       ;
;	   .05  22-JAN-79  L. WEBBER				       ;
;			FIX STACK SETUP IN "SETREG" TERBOT ROUTINE     ;
;			(NOT RELEVANT TO DTE CHK11)		       ;
;	   .06  24-JAN-79  L. WEBBER				       ;
;			USE PAGE 5 INSTEAD OF PAGE 6 FOR MEMORY	       ;
;			TESTING.				       ;
;			(NOT RELEVANT TO DTE CHK11)		       ;
;	   .07  13-FEB-79  L. WEBBER				       ;
;			RECODE ALL EXPRESSIONS WHICH USE COMPLEX       ;
;			RELOCATION.				       ;
;			(NOT RELEVANT TO DTE CHK11)		       ;
;	   .09	28-MAR-79  L. WEBBER				       ;
;			DON'T USE R5 IN CHKBIT; THE REMOTE REPORTING   ;
;			CODE KILLS IT				       ;
;			(NOT RELEVANT TO DTE CHK11)		       ;
;	   .10	28-MAR-79  L. WEBBER				       ;
;	   .11		SAVE & RESTORE R5 IN VARIOUS PLACES THE REMOTE ;
;			REPORTING CODE MIGHT KILL IT		       ;
;			(NOT RELEVANT TO DTE CHK11)		       ;
;	   .12	29-MAR-79  L. WEBBER				       ;
;			FIX TYPO IN TERTIARY; PUT IN CODE TO HALT THE  ;
;			PROCESSOR IF THE TERTIARY GETS AN EARLY TRAP   ;
;			TO 4.					       ;
;			(NOT RELEVANT TO DTE CHK11)		       ;
;	   .14  29-MAR-79  L. WEBBER				       ;
;			TAKE OUT "DO YOU WANT TO CONTINUE"	       ;
;			(CORRESPONDS TO DTE CHK11 2A.12)	       ;
;	   .15	29-MAR-79  L. WEBBER				       ;
;	   .16		MODIFY CR11/CD20 DIFFERENTIATION CODE	       ;
;			(CORRESPONDS TO DTE CHK11 2A.13)	       ;
;	   .17	19-APR-79  L. WEBBER				       ;
;			FIX BUG IN CR11 DIFFERENTIATION CODE	       ;
;			(CORRESPONDS TO DTE CHK11 2A.14)	       ;
;	   .18	19-APR-79  L. WEBBER				       ;
;			FIX TYPO IN FIRST HALF OF TERTIARY	       ;
;			(NOT RELEVANT TO DTE CHK11)		       ;
;	   .19	30-APR-79  L. WEBBER				       ;
;			FIX REGISTER DESTRUCTION IN "CHKDEV"	       ;
;	   .20	21-JUN-79  L. WEBBER				       ;
;			ADD DEVICE CHECKOUT FOR KDZ'S KMCS	       ;
;			(CORRESPONDS TO DTE CHK11 2A.16)	       ;
;	   .21	10-AUG-79  L. WEBBER				       ;
;			MODIFY MEMORY MANAGEMENT TEST TO SET UP	       ;
;			PDR 5 BEFORE USING IT			       ;
;			(CORRESPONDS TO DTE CHK11 2A.17)	       ;
;	x3.01	18-jun-81  r. platukis
;		change memory test to do only try 2 bits
;		prevent logging across DMC line
;
;	x3.02	12-aug-81  r. platukis
;		modify routine PARM in TERBOT to store host id number
;		in the parameter area in top32.
;
;	X3.03	29-dec-81  L. Webber
;		put DMC logging code back in (but leave room for it
;		to be patched out)
;
;	X3.04	1-jun-82  A. Peckham
;		Add ^T code to allow progress update of loader.
;
;	X3.05	5-jun-82  A. Peckham
;		Enable transmit/receive timers
;
;
;
;**********************************************************************;
.PAGE
	.SBTTL CHKDEF - DEFINE THE HARDWARE THAT CHK11 WILL TEST
				;
				;
	PDP11 = 34.		; EXPECTED CPU IS 11/34
				;
;;;;	CKSTD = 0		; SYSTEM CONFIGURATION IS PDP-11 STANDARD
	CKDN2X = 1!2!40		; SYSTEM CONIGURATION IS DN20, DN21, OR DN25
				;  (SPECIFIED BY BIT NUMBERS SET IN CKDN2X DEF -
				;    B0 SAYS DN20, B1 SAYS DN21, B5 SAYS DN25)
	INCLUD	= -1		;
	EXCLUD	= 0		;
				;
;	CKNODV	= 0		; IF DEFINED, LIST NONEXISTENT DEVICES
				;
	M$$MGE	= 0		; IF DEFINED, ASSEMBLE FOR MAPPED SYSTEM
				;
				;
				;
	FTCD20	= INCLUD
	FTCR11	= INCLUD
	FTDH11	= EXCLUD
		NDH11	= 1&FTDH11	;NUMBER OF DH11'S
	FTDJ11	= EXCLUD
	FTDL10	= EXCLUD
	FTDL1A	= EXCLUD
	FTDL1E	= INCLUD
	FTDM11	= INCLUD&FTDH11	;DM11BB DEPENDS ON EXISTENCE OF DH11
		DM.TIM	= 80.	; DM11BB SETTLE TIME IN MEM CYCLES
	FTDMC	= INCLUD
	FTDN11	= EXCLUD
	FTDP11	= EXCLUD
	FTDQ11	= EXCLUD
		SPCVFY	= EXCLUD&FTDQ11 ;DQ11 SPECIAL CHARACTER TEST
	FTDS11	= EXCLUD
	FTDTE	= INCLUD
	FTDU11	= EXCLUD
	FTDUP1	= INCLUD
	FTDZ11	= INCLUD
	FTKG11	= EXCLUD
	FTKMC	= INCLUD&FTDMC	;KMC IS SUPERSET OF DMC
		FTKMCL	= EXCLUD&FTKMC	;INCLUDE ONLY IF CRAM IMAGE IS SUPPLIED
	FTLE11	= INCLUD
	FTLP20	= INCLUD
	FTMD11	= EXCLUD
	FTPA61	= EXCLUD
	FTPP11	= EXCLUD
	FTPR11	= EXCLUD
	FTRH11	= EXCLUD
	FTRK11	= EXCLUD
	FTRX11	= EXCLUD
	FTTC11	= EXCLUD
	FTTM11	= EXCLUD
.PAGE
	.SBTTL END OF MODULE CHKDEF
	.SBTTL
;****************************************************************
;
;	END OF CHKDEF
;
;****************************************************************
.PAGE
	.TITLE S - VARIOUS SYMBOL AND MACRO DEFINITIONS 22 FEB 77
	.SBTTL S - VARIOUS SYMBOL AND MACRO DEFINITIONS 22 FEB 77
;
;
;
;
;
;
;
;
;
;
;
;
;	Copyright 1974, 1975, 1976,1977
;	Digital Equipment Corp., Maynard Mass.
;
;	Sept 25,1974 - DMCC/EGF/LAD/EJW/TEP
;
;
;
;
;
;
;
;
;
;
;
;
	VRS	= 02		;FILE EDIT NUMBER
.PAGE
	.ENABL	LC		;LOWER CASE IS LOWER CASE
	.ENABL	AMA		;USE ABSOLUTE RATHER THAN RELATIVE PC ADDRESSING
;;;;	.DSABL	GBL		;DISABLE GLOBAL REFERENCES
;;;;	.LIST	MC,MD,ME	;
;;;;	.NLIST	CND		;
;;;;	.LIST	MEB		;LIST ONLY CODE PRODUCING PARTS OF MACROS
				;
;	DGUTS NON ZERO REQUESTS THE "DON'T GIVE UP THE SHIP" FAILSOFT FEATURE
;
.IIF NDF DGUTS,DGUTS=0
;
.IF NE DGUTS
		;IF WE'RE NOT TO GIVE UP THE SHIP, TURN OFF DEBUGGING TRAPS
		;THEN WE'LL DIE ONLY ON HARD ERRORS.
	DEBUG=0
	FTASRT=0
	FT.CHK=0
.ENDC
;
.IIF NDF FT.HLP,FT.HLP=	1	;1 = TYPE OUT STOPCD INFORMATION
;
.IIF NDF DEBUG,DEBUG=1		;LEVEL OF DEBUG CODE INCLUDED
				; 0 = NONE = KEEP AS SMALL AS POSSIBLE
				; 1 = SOME - KEEP TRACKS, DIE ON SOME ERRORS
				; -1 = DIE ON ALL ERRORS
;
.IIF NDF STKLEN,STKLEN=	200	;LENGTH OF SYSTEM STACK
;
.IIF NDF FT.CHK,FT.CHK=	1	;1 EQUALS CHECK STUFF ON FLY
;
.IIF NDF PASS,PASS=0	;COUNT ASSEMBLER PASSES
	PASS=PASS+1
.PAGE
.SBTTL	STOPCD'S
		;
S..AMC	= 0	;ASSERT MACRO CALL - DEFAULT CODE
S..NXM	= 1	;BUS TRAPS'S, ADDRESS ERROR'S, ETC.
S..DL1	= 2	;DL10 ERRORS
S..DTE	= S..DL1 ;DTE20 ERRORS (NOTE - SAME AS DL10)
S..CNK	= 3	;CHUNKS ARE MESSED UP
S..ILS	= 4	;ILLEGAL INSTRUCTION
S..CTY	= 5	;NO CTY
S..MEM	= 6	;MEMORY ERROR (E.G. PARITY, OR CAN'T READ WRITE BITS)
S..KW11	= 7	;KW11 ERROR
S..NCN	= 10	;NO CONNECTION FOR RECEIVED DATA
		; OR CONNECTION NUMBER USED BY SOME OTHER NODE
S..BDT	= 11	;BAD DATA TYPE REQUESTED BY 10
S..CHK	= 12	;CHECK 11 ERROR
S..MPD	= 13	;MAPPED ASSEMBLY RUNNING IN UNMAPPED HARDWARE
S..MMG	= 14	;MEMORY MANAGEMENT ERROR
		;
;STOP CODE MACRO
;	FIRST ARGUMENT IS CODE FOR STOP
;	SECOND ARGUMENT IS SEVERITY
;
.MACRO	STOPCD	CD,TYPE
	    .IF NB <CD>
	S.....=S..'CD
	    .IFF ;NB <CD>
	S.....=0
	    .ENDC ;NB <CD>
	Z=1
.IIF IDN <.'TYPE>,<.DEBUG>,	Z=DEBUG
.IIF NE Z,	TRAP S.....
	S.....=0
.ENDM	STOPCD
.PAGE
.SBTTL	GENERAL MACRO DEFINITIONS
;
;
.MACRO COUNT A,?X
	INC	A+2
	BNE	X
	INC	A
X:
.ENDM	COUNT
;
; REGISTER SAVE MACRO
;
.MACRO	SAVE	A
	.IRP	X,<A>
	MOV	X,-(SP)		;PUSH X ON THE STACK
	.ENDR ;IRP X
.ENDM	SAVE
;
; REGISTER RESTORE MACRO
;
.MACRO	RESTORE	A
	.IRP	X,<A>
	MOV	(SP)+,X		;POP X OFF THE STACK
	.ENDR ;IRP X
.ENDM	RESTORE
;
.MACRO	FALLR	DEST
.IIF NE DEST-.	.ERROR	DEST-.	;**** ERRONEOUS CODE FALL THROUGH ATTEMPTED ****
.ENDM	FALLR
;
.MACRO	.INC	ARG
	ARG	= ARG + 1
.ENDM	.INC
;
.MACRO	.DEC	ARG
	ARG	= ARG - 1
.ENDM	.DEC
;
.MACRO	LESSER	A,B,C	;DEFINE A AS THE LESSER OF B AND C
	    .IF GT B-C
	A	= C
	    .IFF
	A	= B
	    .ENDC
.ENDM	LESSER
;
.MACRO	GREATR	A,B,C	;DEFINE A AS THE GREATER OF B AND C
	LESSER	A,C,B
.ENDM	GREATR
;
.PAGE
.MACRO	NAMEBT	REG,IPOSMS,LIST
	    .IF NB IPOSMS
	POSMSK = IPOSMS
	    .ENDC
	    .IF  DF POSMSK
	    .IF EQ POSMSK
	POSMSK = 100000
	    .ENDC
	    .IFF
	POSMSK = 100000
	    .ENDC
	.IRP	NAME,<LIST>
	    .IF EQ POSMSK
	.ERROR	NAME	;**** POSITION MASK UNDERFLOW ****
	    .ENDC
	    .IF NB NAME
	NAME = POSMSK
	    .ENDC
	POSMSK = <POSMSK/2>&77777
	.ENDR ;IRP NAME
.ENDM	NAMEBT
;
.MACRO	NAMASC
	$$ = 0
	.IRP	X,<NUL,SOH,STX,ETX,EOT,ENQ,ACK,BEL>
	X = $$
	.INC	$$
	.ENDR	;IRP X
	;
	.IRP	X,<BS,HT,LF,VT,FF,CR,SO,SI>
	X = $$
	.INC	$$
	.ENDR	;IRP X
	;
	.IRP	X,<DLE,DC1,DC2,DC3,DC4,NAK,SYN,ETB>
	X = $$
	.INC	$$
	.ENDR	;IRP X
	;
	.IRP	X,<CAN,EM,SUB,ESC,FS,GS,RS,US>
	X = $$
	.INC	$$
	.ENDR	;IRP X
	;
	DEL = 177
	;
	ERRCHR = '\!200		;DEC STD ERROR CHARACTER
	;
.ENDM	NAMASC
;
.MACRO	FIELD	NAME,HI,LO
	NAME	= <HI-1+HI>&^C<LO-1>
.ENDM	FIELD
;
.PAGE
; HIDDEN HERE IN THE SOURCE CODE ARE A WHOLE BUNCH OF DEBUGGING
;    AND OTHER SPECIAL MACROS WHICH ARE SUPRESSED IN THE ASSEMBLY IN
;    THE INTEREST OF SQUATTER LISTINGS (AND FASTER ASSEMBLING)
	.NLIST
	.REPT	0
;MACRO TO HANDLE QUEUES
;
; 1ST ARGUMENT IS NAME OF QUEUE
; 2ND ARGUMENT IS MAXIMUM NUMBER OF ENTRIES IN QUEUE
; 3RD ARGUMENT IF PRESENT IS NUMBER OF BYTES IN EACH ENTRY
;
.MACRO	QUEUE	QUE,SIZ,ESZ
;
.IIF B <ESZ>,QUE'.SIZ=<SIZ+1>*2
.IIF NB <ESZ>,QUE'.SIZ=<SIZ+1>*ESZ
QUE'.PTR:	QUE'.QUE		;QUEUE PUTTER
QUE'.TKR:	QUE'.QUE		;QUEUE TAKER
QUE'.QUE:	.BLKB	QUE'.SIZ
;
.ENDM	QUEUE
;
;MACRO TO GIVE OPER MESSAGES
;
.MACRO	TATTLE	ARG
	    .IF NE FT.HLP
	MOV	#ARG'.MSG,LB.CTY(J)
	    .ENDC
.ENDM	TATTLE
.PAGE
;MACRO TO TRACE THINGS
;
.MACRO	TRACE	ARG
Q= FTRACE
	    .IF NB ARG
	    .IF DF FT'ARG'.T
	Q	= FT'ARG'.T&FTRACE
	    .IFF
	.PRINT ;FT'ARG'.T NOT DEFINED
	    .ENDC
	    .IF NE Q
	JSR	PC,TRACE.
	    .ENDC
.ENDM	TRACE
;
.PAGE
;NESTED MACROS FOR BUILDING VARIOUS BLOCK STRUCTURES
;
.MACRO	BLOCK	TYPE
	$$$OFF=0	;START WITH ZERO OFFSET
;
.MACRO ITIS A,B
.LIST
A=B
.NLIST
.ENDM	ITIS
;
.MACRO	X	Q,QQ
	$$$OFF=<$$$OFF+1>&177776	;EVEN OFFSET FORCED
	    .IF  NB <Q>
	ITIS	TYPE'.'Q,\$$$OFF
	    .ENDC
	    .IF NB <QQ>
	$$$OFF=$$$OFF+<QQ>+<QQ>
	    .IFF
	$$$OFF=$$$OFF+2
	    .ENDC
.ENDM	X
;
.MACRO	XX	Q,QQ
	    .IF NB <Q>
	ITIS	TYPE'.'Q,\$$$OFF
	    .ENDC
	    .IF NB <QQ>
	$$$OFF=$$$OFF+<QQ>
	    .IFF
	$$$OFF=$$$OFF+1
	    .ENDC
.ENDM	XX
;
.ENDM	BLOCK
.PAGE
;INLINE MACRO TO COUNT OCCURANCES
;
.IIF NDF FTWDDL,FTWDDL=0
;
	    .IF NE FTWDDL!DEBUG!FT.CHK
	FTWDDL	= 1
;
.MACRO	TWLAB.	QI
	.LIST
	TW.'QI	= .-2
	.NLIST
	FTWDDL	= FTWDDL+1
.ENDM	TWLAB.
;
.MACRO	TWIDDLE	QVAL
	    .IF NB <QVAL>
	MOV	QVAL,#0
	    .IFF
	INC	#0
	    .ENDC
	TWLAB.	\FTWDDL
.ENDM	TWIDDLE
	    .IFF
.MACRO	TWIDDLE	QVAL
.ENDM	TWIDDLE
	    .ENDC ;NE FTWDDL!...
;
;
;MACROS FOR CONSISTENCY CHECKING
;
;
	    .IF NE FT.CHK
	FTASRT	= 1
.MACRO	CHK	X
	ASSERT	X
.ENDM	CHK
;
.MACRO	CNKCHK	Q	;CHECK CHUNK ADR IS PLAUSIBLE
	ASSERT CHUNK Q
.ENDM	CNKCHK
;
	    .IFF
;
.MACRO	CHK	X
.ENDM	CHK
;
.MACRO	CNKCHK
.ENDM	CNKCHK
;
	    .ENDC ;NE FT.CHK
	.ENDR	;END OF THE HIDDEN MACRO BLOCK
	.LIST
.PAGE
.SBTTL	PDP-11 EIS EMULATORS
;
;MACROS TO SIMULATE INSTRUCTIONS FOR SIMPLE PDP11'S
;
.IF LT <PDP11-30.>
;
;MACRO TO SIMULATE SOB ON SIMPLE PDP11'S
;
.MACRO	SOB	CNT,WHERE
.IIF GT WHERE-., .ERROR	0; SOB FORWARD BRANCH ????
.IIF NE <.-WHERE>&^C176, .ERROR	WHERE; SOB BRANCH RANGE ????
	    .IF NE WHERE-.
	DEC	CNT
	BNE	WHERE
	    .IFF
	BRLOC=.
	DEC	CNT
	BNE	BRLOC
	    .ENDC ;NE WHERE-.
.ENDM	SOB
;
;MACRO TO DO AN XOR FOR SIMPLE PDP11'S
;
; ARGUMENTS:	A-- IS ALWAYS A REGISTER, B-- REFLECTS
;		THE DESTINATION OPERAND, C-- IS USUALLY ON THE STACK
;
.MACRO	XOR2	A02,B02,B12,B22,C02,C12,C22
	MOV	A02,C02
	BIC	B02,C12
	BIC	A02,B12
	BIS	C22,B22
.ENDM	XOR2
;
.MACRO	XOR1	A01,B01,B11,B21
	XOR2	A01,B01,B11,B21,-(SP),(SP),(SP)+
.ENDM	XOR1
;
.MACRO	XORERR	AV,BV,DB
	    .IF B DB
.ERROR	74000; XOR SOURCE ('AV') NOT A REGISTER ???
	    .IFF
.ERROR	<74000+<AV*100>+BV>; XOR WITH DEST DB IS NOT SUPPORTED ????
	    .ENDC
	HALT
.ENDM	XORERR
;
.MACRO	XMODE	Y,S,D
	XMOD'Y	\QD,S,D
.ENDM	XMODE
;
.MACRO	XMOD0	X,S,D
	XOR1	S,D,D,D
.ENDM	XMOD0
;
.MACRO	XMOD10	X,S,D
	XOR1	S,D,D,D
.ENDM	XMOD10
;
.MACRO	XMOD20	X,S,D
	XOR1	S,(R'X),(R'X),(R'X)+
.ENDM	XMOD20
;
.MACRO	XMOD30	X,S,D
	XOR1	S,@(R'X),@(R'X),@(R'X)+
.ENDM	XMOD30
;
.MACRO	XMOD40	X,S,D
	XOR1	S,-(R'X),(R'X),(R'X)
.ENDM	XMOD40
;
.MACRO	XMOD50	X,S,D
	XOR1	S,@-(R'X),@(R'X),@(R'X)
.ENDM	XMOD50
;
.MACRO	XMOD60	X,S,D
	XOR1	S,D,D,D
.ENDM	XMOD60
;
.MACRO	XMOD70	X,S,D
	XOR1	S,D,D,D
.ENDM	XMOD70
;
.MACRO	XOR	A,B
	.NTYPE	QA,A	;QA IS 6-BIT SOURCE SPEC
	.NTYPE	QB,B	;QB IS 6-BIT DEST SPEC
	QC=QB&70	;QC IS DEST ADDRESS MODE
	QD=QB&7		;QD IS DEST ADDRESS REGISTER
	    .IF NE QA&^C7 ;QA MUST BE REGISTER DIRECT
	XORERR	\QA
	    .IFF
			;QA IS REGISTER DIRECT, DECODE DEST SPEC
	    .IF LE <QD-5> ;DEST USES USER GPR (0-5)
	XMODE	\QC,A,B	;CALL MODE SELECTOR MACRO BASED ON QC
	    .IFF
			;DEST USES SP OR PC
	.IIF EQ <QC-0>	;MODE IS REGISTER DIRECT (ERROR)
	.IIF EQ <QB-06>,	XORERR	\QA,\QB,B
	.IIF EQ <QB-07>,	XORERR	\QA,\QB,B
	.IIF EQ <QC-1>	;MODE IS REGISTER DEFERRED
	.IIF EQ <QB-16>,	XOR1	A,2(SP),2(SP),(SP)
	.IIF EQ <QB-17>,	XORERR	\QA,\QB,B
	.IIF EQ <QC-2>	;MODE IS POP (PC IMMEDIATE)
	.IIF EQ <QB-26>,	XORERR	\QA,\QB,B
	    .IF EQ <QB-27>
	MOV	B,.+22
	XOR1	A,.+12,.+6,(PC)+
	.WORD	0	;UNLABELED LITERAL
	    .ENDC
	.IIF EQ <QC-3>	;MODE IS DEFER AND POP (PC ABSOLUTE)
	.IIF EQ <QB-36>,	XOR1	A,@2(SP),@2(SP),@(SP)+
	.IIF EQ <QB-37>,	XOR1	A,B,B,B
	.IIF EQ <QC-4>	;MODE IS PUSH
	.IIF EQ <QB-46>,	XORERR	\QA,\QB,B
	.IIF EQ <QB-47>,	XORERR	\QA,\QB,B
	.IIF EQ <QC-5>	;MODE IS PUSH AND DEFER
	.IIF EQ <QB-56>,	XORERR	\QA,\QB,B
	.IIF EQ <QB-57>,	XORERR	\QA,\QB,B
	.IIF EQ <QC-6>	;MODE IS INDEXED
	.IIF EQ <QB-66>,	XOR1	A,2+B,2+B,B
	.IIF EQ <QB-67>,	XOR1	A,B,B,B
	.IIF EQ <QC-7>	;MODE IS DEFERRED INDEXED
	.IIF EQ <QB-76>,	XORERR	\QA,\QB,B
	.IIF EQ <QB-77>,	XOR1	A,B,B,B
	    .ENDC ;USER GPR VS. SP/PC
	    .ENDC ;QA IS REGISTER DIRECT
.ENDM	XOR
;
.ENDC;.IF LT <PDP11-30.>
;
.IF LT <PDP11-45.>
	;MACRO TO SET PROCESSOR LEVEL
.MACRO	SPL	Q
	    .IF	NE Q
	BIS	#BR7,PS			;SET PROCESSOR STATUS TO LEVEL 7
	    .ENDC
	    .IF NE <Q-7>
	BIC	#40*<7&<^C<Q>>>,PS	;NOW DROP TO LEVEL Q
	    .ENDC
.ENDM	SPL
.ENDC;.IF LT <PDP11-45.>
;
;MACRO TO SIMULATE EXCH INSTRUCTION
;
.MACRO	EXCH	A,B
	MOV	A,-(P)		;SAVE C(A) ON THE STACK
	MOV	B,A		;PUT C(B) INTO A
	MOV	(P)+,B		;PUT ORIGINAL C(A) INTO B
.ENDM	EXCH
;
;MACRO TO GENERATE AN .ASCIZ STRING TERMINATED WITH .EVEN
;
.MACRO	ASCIZ	STRING
	.ASCIZ	\STRING\
	.EVEN
.ENDM	ASCIZ
.PAGE
.SBTTL	SYMBOL DEFINITIONS
;
R0	= %0
R1	= %1
R2	= %2
R3	= %3
R4	= %4
R5	= %5
SP	= %6		;STACK POINTER
PC	= %7
;
PS	= 177776	;PROCESSOR STATUS WORD
	;	000001	;C (CARRY)
	;	000002	;V (OVERFLOW)
	;	000004	;Z (ZERO)
	;	000010	;N (NEGATIVE)
	;	000020	;T (TRAP)
	;	000340	;PRIORITY LEVEL (0-7)
	;	004000	;REGISTER SET
	;	030000	;PREVIOUS MODE
	;	140000	;CURRENT MODE
	;		;MODE: 00=KERNEL, 01=SUPERVISOR, 11=USER
SW=177570	;ADDRESS OF SWTCHES
;
B0	= 1
B1	= 2
B2	= 4
B3	= 10
B4	= 20
B5	= 40
B6	= 100
B7	= 200
B8	= 400
B9	= 1000
B10	= 2000
B11	= 4000
B12	= 10000
B13	= 20000
B14	= 40000
B15	= 100000
;
FIELD	ALLBTS,B15,B0
;
;DEFINE PROCESSOR LEVELS
;
BR0	= 0*40
BR1	= 1*40
BR2	= 2*40
BR3	= 3*40
BR4	= 4*40
BR5	= 5*40
BR6	= 6*40
BR7	= 7*40
;
PR0	= 0
PR1	= 40
PR2	= 2*PR1
PR3	= 3*PR1
PR4	= 4*PR1
PR5	= 5*PR1
PR6	= 6*PR1
PR7	= 7*PR1
.PAGE
.SBTTL	HARDWARE DEFINITIONS
.SBTTL		VECTORS
;
.MACRO	DEFVEC	TYP,VQ,LQ
	TYP'VEC=	VQ		;VECTOR FOR TYP IS VQ
	    .IF B LQ
	TYP'LVL=	7		;DEFAULT LEVEL IS LEVEL 7
	    .IFF
	TYP'LVL=	LQ		;LEVEL OF TYP IS LQ
	    .ENDC ;B LQ
.ENDM	DEFVEC
;
	DEFVEC	NXM,04	;BUS-TIMEOUT INTERRUPT
	DEFVEC	ILS,10	;ILLEGAL INSTRUCTION INTERRUPT
	DEFVEC	BPT,14	;BREAKPOINT TRAP
	DEFVEC	IOT,20	;I/O TRAP INSTRUCTION
	DEFVEC	PWF,24	;POWER FAIL INT'S
	DEFVEC	EMT,30	;EMT CALL'S
	DEFVEC	TRP,34	;TRAP INSTRUCTION
	DEFVEC	MMG,250	;MEMORY MANAGEMENT FAULT
.PAGE
.SBTTL		DEVICES
	.SBTTL		CD20 - PUNCHED CARD READER
;
; CD20 HARDWARE DEVICE REGISTER DEFINITIONS
;
CD.LVL	= 4		;BUS REQUEST PRIORITY
CD.VEC	= 230		;CD20 VECTOR
;
	CD.STS = 177160
	CDST = 0		;FIRST STATUS AND CONTROL REGISTER
	NAMEBT	CDST,0,<CD.ERR,CD.RDC,CD.EOF,CD.OFL,CD.DER,CD.DLT>
	NAMEBT	,,<CD.NXM,CD.PWC,CD.RDY,CD.IE,CD.B17,CD.B16>
	NAMEBT	,,<CD.ONL,CD.HPE,CD.PAC,CD.GO>
		CD.XAD	= CD.B17!CD.B16	;HIGH ORDER BUS ADDRESS MASK
			.REPT	0
		CD.ERR	= OR OF ALL ERROR CONDITIONS, RO
		CD.RDC	= READER CHECK, PHYSICAL READER ERROR, RO
		CD.EOF	= END OF FILE BUTTON PRESSED, RO
		CD.OFL	= OFF LINE, RO
		CD.DER	= DATA ERROR, ILLEGAL PACKED CHAR, RO
		CD.DLT	= DATA LATE, NPR TIMING ERROR, RO
		CD.NXM	= NONEXISTENT MEMORY REFERENCE DURING DMA, RO
		CD.PWC	= POWER CLEAR, INITIALIZE CONTROLLER, WO
	
		CD.RDY	= CONTROLLER READY FOR ACTION, RO
		CD.IE	= INTERRUPT ENABLE, RW
		CD.B17,CD.B16	= HIGHEST ORDER BUS ADDRESS BITS, RW
		CD.ONL	= TRANSITION TO ONLINE OCCURRED, RO
		CD.HPE	= HOPPER EMPTY, RO
		CD.PAC	= READ MODE SWITCH, RW
		CD.GO	= START READER COMMAND, WO
			.ENDR
				;
CDCC	= 2			;COLUMN COUNT REGISTER
	CD.COL = 80.		;80 COLUMN READER
				;
CDBA	= 4			;CURRENT ADDRESS REGISTER
				;
CDDB	= 6			;DATA BUFFER
	; IMAGE MODE DEFINITIONS
	NAMEBT	CDDB,0,<CD.CER,IDZ2,IDZ1,IDZ0,IZ12,IZ11,IZ00,IZ01>
	NAMEBT	,,<IZ02,IZ03,IZ04,IZ05,IZ06,IZ07,IZ08,IZ09>
			.REPT	0
		CD.CER	= CHARACTER PACKING ERROR
		IDZ-	= IMAGE MODE PACKED DIGIT ZONE BITS
		IZ--	= IMAGE MODE ZONE PUNCH BITS
			.ENDR
				;
	; PACKED MODE DEFINITIONS
	NAMEBT	CDDB,200,<PZ12,PZ11,PZ00,PZ09,PZ08,PDZ2,PDZ1,PDZ0>
			.REPT	0
		PZ--	= PACKED MODE ZONE PUNCH BITS
		PDZ-	= PACKED MODE PACKED DIGIT ZONE BITS
			.ENDR
				;
CDST2 = CDDB			;SECOND STATUS AND CONTROL REGISTER
				;  MULTIPLEXED USE OF DATA BUFFER REGISTER
	NAMEBT	CDST2,0,<ST2ENB,CD.RCK,CD.PCK,CD.SCK>
	NAMEBT	,,<ZT12,ZT11,ZT00,ZT01,ZT02,ZT03,ZT04,ZT05,ZT06,ZT07,ZT08,ZT09>
		ZTALL	= 7777
			.REPT	0
		ST2ENB	= CDST2 ENABLE
		RCHK	= READ CHECK (CARD ERROR)
		PCHK	= PICK CHECK (FEED ERROR)
		SCHK	= STACK CHECK (FEED ERROR)
		ZT--	= ZONE TEST BITS
		ZTALL	= OR OF ALL ZONE TEST BITS
			.ENDR
				;
CDHRSZ = 10			;SIZE OF REGISTER BLOCK IN BYTES
.PAGE
.SBTTL		CR11 - PUNCHED/MARK SENSE CARD READER
;
CR.LVL= 6		; PROCESSOR LEVEL FOR CR11 INTERRUPTS
CR.VEC= 230
;
CR0STS = 177160
CR.STS= 177160		; CR11 STATUS REGISTER
;
	CR.ERR= B15	; ERROR
	CR.DNE= B14	; CARD DONE
	CR.HCK= B13	; HOPPER CHECK
	CR.MCK= B12	; MOTION CHECK
	CR.TIM= B11	; TIMING ERROR
	CR.OLN= B10	; BACK ONLINE AFTER BEING OFF
	CR.BSY= B9	; BUSY
	CR.RDY= B8	; NOT READY
	CR.CDN= B7	; COLUMN DONE
	CR.INE= B6	; INTERRUPT ENABLE
	CR.EJT= B1	; EJECT
	CR.CFD= B0	; CARD FEED
	
CR.DAT= 177162		; 12 LOW ORDER BITS ARE DATA
.PAGE
.SBTTL		CTY - CONSOLE TELETYPE
;
;CTY HARDWARE BITS
;
CTISTS = 177560
CTICHR = 177562
CTIVEC=	60
CTILVL=	4	; PRIORITY LEVEL
;
	CI.INE=	B6		; CTY INPUT INTERRUPT ENABLE
;
CTOSTS = 177564
CTOCHR = 177566
CTOVEC=	64
CTOLVL=	4	; PRIORITY LEVEL
;
	CO.INE=	B6		; CTY OUTPUT INTERRUPT ENABLE
	CO..MM=	B2		; CTY OUTPUT MAINT MODE
.PAGE
.SBTTL		DH11 - ASYNCHRONOUS SERIAL LINE MULTIPLEXER
DHBASE=	160020	;HARDWARE ADR OF FIRST DH11
DH.LVL=	7		;DH11 INTERRUPT LEVEL
			; 1ST WORD IS SYSTEM CONTROL REGISTER
	DH.RIE=	B6	;RECEIVE INTERRUPT ENABLE
	DH..RI=	B7	;RECEIVE INTERRUPT
	DH.CNX=	B8	;CLEAR NON EX MEM INT
	DH..MM=	B9	;MAINTANCE MODE
	DH.NXM=	B10	;NON EXISTENCE MEMORY
	DH..MC=	B11	;MASTER CLEAR
	DH.SIE=	B12	;STORAGE INTERRUPT ENABLE
	DH.TIE=	B13	;TRANSMIT INTERRUPT ENABLE
	DH..SI=	B14	;STORAGE INTERRUPT
	DH..TI=	B15	;TRANSMIT INTERRUPT
DH.NRC=2		; 2ND WORD IS NEXT RECEIVED CHAR REGISTER
DH.LPR=4		; 3RD WORD IS LINE PARAMETER REGISTER
DH.CAR=6		; 4TH WORD IS CURRENT ADDRESS REGISTER
DH.BCR=10		; 5TH WORD IS BUFFER COUNT REGISTER
DH.BAR=12		; 6TH WORD IS BUFFER ACTIVE REGISTER
DH.BRK=14		; 7TH WORD IS BREAK CONTROL REGISTER
DH.SSR=16		; 8TH WORD IS SILO STATUS REGISTER
;
		;ON CHARS OUT OF SILO
	DHROVR=	B14		;DATA OVERRUN
	DHRFER=	B13		;FRAMMING ERROR
	DH.VDP=	B15	;VALID DATA PRESENT
	DH.DOV=	B14	;DATA OVER RUN
	DH..FE=	B13	;FRAMING ERROR
	DH..PE=	B12	;PARITY ERROR
;
		;FOR LINE PARAMETERS
	DH.AEE=	B15	;AUTO ECHO ENABLE
	DH..HD=	B14	;HALF DUPLEX
	DH..OP=	B5	;ODD PARITY
	DH.PEN=	B4	;PARITY ENABLED
	DH.2SB=	B2	;2 STOP BITS
	DH.CL5=	0	;5 BIT
	DH.CL6=	B0	;6 BIT
	DH.CL7=	B1	;7 BIT
	DH.CL8=	B1!B0	;8 BIT
.PAGE
.SBTTL		DJ11 - ASYNCHRONOUS SERIAL LINE MULTIPLEXER
.PAGE
.SBTTL		DL10 - UNIBUS-TO-MBUS INTERFACE
;
;DL10 - UNIBUS TO DECSYSTEM-10 MEMORY BUS INTERFACE
;
DL.BAS=	100000			;BASE ADDRESS FOR 10 MEMORY
DLBASE=	DL.BAS			;
DL.VEC=	170			;VECTOR ADR FOR DL10
DL.LVL=	4			;CHANNEL FIVE
;
DL.STS=DLBASE	;1ST WORD IS STATUS
	DL.11I=	B15		; BIT 15 - 11 INT(INTERRUPTS IF 11-INT-ENB SET)
	DL.11C=	B14		; BIT 14 - CLEAR 11 INT
	DL.10I=	B13		; BIT 13 - 10 INT
	DL.10C=	B12		; BIT 12 - CLEAR 10 INT
	DL.NXM=	B11		; BIT 11 - NXM(INTERRUPTS IF ERR ENB SET)
	DL.CNX=	B10		; BIT 10 - CLEAR NXM
	DL.PAR=	B9		; BIT 09 - PAR ERR(INTERRUPTS IF ERR ENB SET)
	DL.CPE=	B8		; BIT 08 - CLEAR PAR ERR
	DL.WCO=	B7		; BIT 07 - WCOV(INTERRUPTS IF ERR ENB SET)
	DL.CWC=	B6		; BIT 06 - CLEAR WCOV
	DL.PEN=	B5		; BIT 05 - PORT ENABLE
	DLPENB=	DL.PEN		;
	DL.B04=	B4		; BIT 04 - (GUESS !)
	DL.ERE=	B3		; BIT 03 - ERR ENABLE
	DL.INE=	B2		; BIT 02 - 11 INT ENB
	DL.B01=	B1		; BITS 00 & 01 - PIA
	DL.B00=	B0		;
.PAGE
.SBTTL		DL11 - ASYNCHRONOUS SERIAL LINE INTERFACE
;
;
DLDADR=175610	; DL11 NUMBER ZERO DEVICE ADDRESS
DLDSIZ=10	; LENGTH OF DEVICE ADDRESS ASSIGNMENT
;
;	CONTROL REGISTERS
;
;
DLRSTS=0		; RECEIVER STATUS AND CONTROL
;
;		BIT ASSIGNMENTS
	DL..RE=B0	; PAPER TAPE READER ENABLE (R/W)
	DL.DTR=B1	; DATA TERMINAL READY (R/W)
	DL.RTS=B2	; REQUEST TO SEND (R/W)
	DL.2XM=B3	; SECONDARY XMIT (R/W)
	DL.DIE=B5	; DATASET INTERRUPTS ENABLE (R/W)
	DL.RIE=B6	; RECEIVER INTERRUPTS ENABLE (R/W)
	DL.ROK=B7	; RECEIVER DONE (R)
	DL.2RC=B10	; SECONDARY RECEIVE (R)
	DL.RGO=B11	; RECEIVER ACTIVE (R)
	DL.CAR=B12	; CARRIER PRESENT (R)
	DL.CTS=B13	; CLEAR TO SEND (R)
	DL.RNG=B14	; DATASET RING (R)
	DL.DSC=B15	; DATASET STATUS CHANGE (R)
;
;
DLRBUF=2	; RECEIVED CHARACTER BUFFER
;
;		BIT ASSIGNMENTS
	DL..RC=B0!B1!B2!B3!B4!B5!B6!B7	;THE RECEIVED CHARACTER (R)
	DL..PE=B12	; PARITY ERROR (R)
	DL..FE=B13	; FRAMING ERROR (R)
	DL.OVR=B14	; RECEIVER OVER RUN (R)
	DL.ERR=B15	; RECEIVER ERROR DETECTED (R)
;
;
;
DLXSTS=4	; XMITTER STATUS AND CONTROL REGISTER
;
;		BIT ASSIGNMENTS
	DL.BRK=B0	; SEND BREAK (W)
	DL..MM=B2	; MAINTAINANCE MODE (R/W)
	DL.XIE=B6	; XMITTER INTERRUPTS ENABLE (R/W)
	DL.XOK=B7	; XMITTER READY FOR NEXT CHARACTDER (R)
;
;
;
DLXBUF=6	; XMITTER CHARACTER BUFFER
;
;	BIT ASSSIGNMENT
	DL..XC=B0!B1!B2!B3!B4!B5!B6!B7	; CHARACTER BEING XMITTED (W)
.PAGE
.SBTTL		DM11BB - MODEM CONTROLLER FOR DH11
;
DMBASE=	170500		;HDW ADR OF FIRST DM11
;
DM.LVL=	7		;PROCESSOR LEVEL FOR DM11BB INTERRUPTS
;
	B.DM11=	170500	;FIRST DM11 ADR
	DM.SCN=	B11	;CLEAR SCANNER
	DM.INI=	B10	;CLEAR MULTIPLEXER
	DM..MM=	B9	;MAINTENANCE MODE
	DM.STP=	B8	;STEP TO NEXT LINE
	DM.DNE=	B7
	DM.IEN=	B6	;INTERRUPT ENABLE
	DM.ENB=	B5	;SCAN ENABLE
	DM.BSY=	B4	;CLEAR SCAN STILL PERCOLATING
	DM.ALI=	B0!B1!B2!B3	;LINE NUMBER FIELD
.PAGE
.SBTTL		DMC11/KMC11 - MICROPROCESSOR BASED COMM CONTROLLER
;
DMC.LVL	= 5
;
	NAMEBT	,0,<MD.RUN,MD.CLR,MD.CWR,MD.SLU,MD.LLU>
	NAMEBT	,,<MD.RMO,MD.RMI,MD.SMP,B7,B6,B5,B4,B3,B2,B1,B0>
			.REPT	0
		MD.RUN	- RUN THE MICROPROCESSOR
		MD.CLR	- CLEAR THE MICROPROCESSOR
		MD.CWR	- CRAM WRITE
		MD.SLU	- STEP LINE UNIT
		MD.LLU	- LOOP LINE UNIT
		MD.RMO	- ROM OUTPUT
		MD.RMI	- ROM INPUT
		MD.SMP	- STEP MICROPROCESSOR
			.ENDR
	.IRP	X,<0,2,4,6>
	SEL'X	= X
	BSEL'X	= X
	.ENDR ;X
	.IRP	X,<1,3,5,7>
	BSEL'X	= X
	.ENDR ;X
.PAGE
.SBTTL		DN11 - AUTODIALER
;
DN.LVL=	7			;PROCESSOR LEVEL FOR DN INTERRUPTS
DNBASE=175200
;
	DN.PWI=	B15		;POWER INDICATE
	DN.ACR=	B14		;ABANDON CALL AND RETRY
	DN.DLO=	B12		;DATA LINE OCCUPIED
	DN.DNE=	B7		;DONE
	DN..IE=	B6		;INTERRUPT ENABLE
	DN.DSS=	B5		;DATA SET STATUS
	DN.PND=	B4		;PRESENT NEXT DIGIT
	DN..MM=	B3		;MAINTENANCE MODE
	DN..ME=	B2		;MASTER ENABLE
	DN..DP=	B1		;DIGIT PRESENT
	DN..CR=	B0		;CALL REQUEST
	DN.DGT=B8+B9+B10+B11	;DIGIT BITS
.PAGE
.SBTTL		DP11 - SYNCHRONOUS LINE INTERFACE
;
DP.LVL=	7	;PROCESSOR LEVEL FOR DP11 INTERRUPTS
;
; "A" RECEIVER STATUS REGISTER  (ADR = XXXXX0)
;
DP..CP=	B12		;CHARACTER PARITY; 1=ODD, 0=EVEN
DP..RA=	B11		;RECEIVE ACTIVE
DP..RD=	B7		;RECEIVE DONE
DP.RIE=	B6		;RECEIVE DONE INTERRUPT ENABLE
DP..MR=	B3		;MISCELLANEOUS RECEIVE
DP..MM=	B2		;MAINTENANCE MODE
DP..HD=	B1		;HALF DUPLEX
DP..SS=	B0		;STRIP SYNC
;
; "B" TRANSMIT AND CONTROL STATUS REG  (ADR = XXXXX2)
;
DP..CF=	B15		;CARRIER FLAG
DP.ROF=	B14		;RECEIVE OVERRUN FLAG
DP.RNG=	B13		;RING FLAG
DP.MRY=	B12		;MODEM READY
DP.CAR=	B11		;CARRIER
DP.CTS=	B10		;CLEAR TO SEND
DP.RTS=	B9		;REQUEST TO SEND
DP..TD=	B7		;TRANSMIT DONE
DP.TIE=	B6		;TRANSMIT DONE INTERRUPT ENABLE
DP.SIE=	B5		;STATUS INTERRUPT ENABLE
DP.MIS=	B4		;MISCELLANEOUS
DP..MT=	B3		;MISCELLANEOUS TRANSMIT
DP..IS=	B1		;IDLE SYNC
DP.DTR=	B0		;TERMINAL READY
.PAGE
.SBTTL		DQ11 - DMA SYNCHRONOUS LINE INTERFACE
;
DQ.LVL=	7		;PROCESSOR LEVEL FOR DQ11 INTERRUPTS
;
; THE BASE ADR FOR THE DQ11 IS CONTAINED IN THE LINE BLOCK
; RECEIVE STATUS ( ADR =XXXXX0 )
;
	DQ.RGO=	B0	; RECEIVE GO
	DQ.SSY=	B1	; STRIP SYNC
	DQ.SEC=	B2	; 0=	PRIMARY,1=SECONDARY
	DQ.HD=	B3	; HALF DUPLEX(=	MASK INPUT WHEN XMT ACTIVE)
	DQ.CIE=	B4	; CHAR INTERRUPT ENABLE
	DQ.RIE=	B5	; RECEIVE DONE INTERRUPT ENABLE
	DQ.RDS=	B6	; RECEIVE DONE (SECONDARY) FLAG
	DQ.RDP=	B7	; RECEIVE DONE (PRIMARY) FLAG
	DQ.CHR=	7400	; CHAR DETECTED
	DQ.ETB=	B8	; CHAR WAS AN ETB
	DQ.ETX=	B9	; CHAR WAS AN ETX
	DQ.ENQ=	B10	; CHAR WAS AN ENQ
	DQ.SYN=	B11	; SPECIAL CHAR WAS A SYNC
	DQ.RAC=	B12	; RECEIVE ACTIVE
;		060000	; USER OPTION
	DQ.VCH=	B15	; VCHAR FLAG
	DQ.RKL=	DQ.RAC!DQ.VCH!DQ.RGO!DQ.CIE	; BITS TO STOP RECEIVER
;
; TRANSMIT STATUS ( ADR = XXXXX2 )
;
	DQ.XGO=	B0	; TRANSMIT GO
;		B1	; IDLE MODE
	DQ.SEC=	B2	; 0=	PRIMARY ACTIVE,1=SECONDARY ACTIVE
	DQ.EIE=	B3	; ERR INTERRUPT ENABLE
	DQ.DIE=	B4	; DATA SET INTERRUPT ENABLE
	DQ.XIE=	B5	; TRANSMIT DONE INTERRUPT ENABLE
	DQ.XDS=	B6	; TRANSMIT DONE(SECONDARY)
	DQ.XDP=	B7	; TRANSMIT DONE(PRIMARY)
	DQ.RTS=	B8	; REQUEST TO SEND
	DQ.DTR=	B9	; DATA TERMINAL READY
	DQ.DSR=	B10	; DATA SET READY
	DQ.RNG=	B11	; RING
	DQ.CAR=	B12	; CARRIER
	DQ.CTS=	B13	; CLEAR TO SEND
;		B14	; USER OPTION
	DQ.DSF=	B15	; DATA SET FLAG
;
; REG/ERR REGISTER ( ADR =XXXXX4 )
;
	DQ.XCL=	B0	; TRANSMIT CLOCK LOSS
	DQ.RCL=	B1	; RECEIVE CLOCK LOSS
	DQ.XLE=	B2	; TRANSMIT LATENCY ERROR
	DQ.RLE=	B3	; RECEIVE LATENCY ERROR
	DQ.XNX=	B4	; TRANSMIT NONEX MEM
	DQ.RNX=	B5	; RECEIVE NONEX MEM
	DQ.BCC=	B6	; RECEIVE BCC ERROR
	DQ.VRC=	B7	; RECEIVE VRC ERROR
;		007400	; REG SELECT FOR REFERENCE TO XXXXX6
	DQ.MEM=	B12	; WRENABLE 060000
	DQ.MBM=	020	; BYTE EQUIVALENT OF ABOVE
;		060000	; MEM EXT OR ENTER T/EXIT T
;		B15	; ERROR INTERRUPT
;
; SECONDARY REGISTERS ( ADR = XXXXX6 )
;
	RG.PRA=	0	; PRIMARY RECEIVE BA
	RG.PRC=	1	; PRIMARY RECEIVE CC
	RG.PTA=	2	; PRIMARY TRANSMIT BA
	RG.PTC=	3	; PRIMARY TRANSMIT CC
	RG.SRA=	4	; SECONDARY RECEIVE BA
	RG.SRC=	5	; SECONDARY RECEIVE CC
	RG.STA=	6	; SECONDARY TRANSMIT BA
	RG.STC=	7	; SECONDARY TRANSMIT CC
;;;;		10	; CHAR DET REG
	RG.SYN=	11	; SYNC REG
	RG.MSC=	12	; MISC REG
	DQ.MC=	B5	; MASTER CLEAR (SORT OF)
;;;;		13	; TRANSMIT BUF
;;;;		14	; SEQUENCE REGISTER
;;;;		15	; RECEIVE BCC
;;;;		16	; TRANSMIT BCC
;;;;		17	; RECEIVE/TRANSMIT POLYNOMIAL
			;
.MACRO	DQREGS	REG,QQ
Z=	RG.'REG
.IIF EQ <Z&10>,Z=	Z+DQ.MBM
	    .IF B,QQ
	MOVB	#Z,5(DQ)	;SET TO ADDRESS SECONDARY REGISTER RG.'REG
	    .IFF ;B <QQ>
	MOVB	#Z,5QQ		;SET TO ADDRESS SECONDARY REGISTER RG.'REG
	    .ENDC ;B <QQ>
.ENDM	DQREGS
.PAGE
;
;	THE SEVEN SWITCHES (PACKAGES) WILL BE LOCATED
;		ON BOARD #M7818 WITHIN THE DQ11 LOGIC BLOCK
;
;
;	PACKAGE #	SWITCH #'S	SWITCH SETTINGS ON RESPECTIVE PACKAGES
;
;	1		 8 - 1		ALL OFF
;
;	2		16 - 9		ALL OFF
;
;	3		24 - 17		ALL OFF
;
;	4		32 - 25	DAS78	 ON, ON,OFF, ON,OFF,OFF, ON,OFF
;					CHARACTER = 055 (ENQ)
;	4		32 - 25 DAS85	 ON, ON, ON, ON, ON,OFF, ON,OFF
;					CHARACTER = 005 (ENQ)
;
;	5		40 - 33	DAS78	 ON, ON,OFF,OFF,OFF, ON, ON, ON
;				DAS85	 ON,OFF,OFF,OFF,OFF, ON, ON, ON
;
;	6		48 - 41	DAS78	 ON, ON, ON, ON, ON, ON,OFF,OFF
;					CHARACTER = 03 (ETX)
;				DAS85	OFF, ON, ON,OFF, ON, ON,ON, ON
;					CHARACTER = 220 (DLE)
;
;	7		56 - 49	DAS78	 ON, ON, OFF, ON, ON,OFF,OFF, ON
;					CHARACTER = 46 (ETB)
;				DAS85	OFF, ON, ON, ON, ON, ON, ON,OFF
;					CHARACTER = 201 (SOH)
.PAGE
.SBTTL		DS11 - SYNCHRONOUS LINE INTERFACE
;
;HARDWARE ADDRESSES
;
DS.AUX=	175600		;AUXILLARY REGISTER
DS.DVA=	175400		;BEGINNING OF LINE DEVICE REGISTERS
DS.VEC=	400		;FIRST DS11 VECTOR
DS.LVL=	7		;PROCESSOR LEVEL OR DS11 INTERRUPTS
;
;BITS IN AUXILLARY REGISTER
;
DS.AD3=B15		;ADAPTER 3 IS PRRSENT IF SET
DS.AD2=B14		;ADAPTER 2 IS PRESENT IF SET
DS.AD1=B13		;ADAPTER 1 IS PRESENT IF SET
;	B12		;NOT USED
;	B11		;NOT USED
;	B10		;NOT USED
;	B9		;PROGRAM VECTOR 9
DS.IVA=B8		;PROGRAM VECTOR 8 - INTERRUPTS START AT 400
;	B7		;DIAG MODE
;	B6		;PROGRAM CLOCK ALLOW
;	B5		;NOT USED
;	B4		;DIAG BIT CNTR CLEAR
;	B3		;DIAG BIT COUNTER 4
;	B2		;DIAG BIT COUNTER 3
;	B1		;DIAG BIT COUNTER 2
;	B0		;DIAG BIT COUNTER 1
;
;
;OFFSETS OF REGISTERS FROM LINE BASE ADDRESS
;
DS.XDR=6		;TRANSMIT DATA REGISTER
DS.XST=4		;TRANSMIT STATUS REGISTER
DS.RDR=2		;RECEIVE DATA REGISTER
DS.RST=0		;RECEIVE STATUS REGISTER
;
;PRIORITY INTERRUPT LEVELS
;
I.DSRD=7		;RECEIVE DATA INTERRUPT
I.DSRS=6		;RECEIVE STATUS INTERRUPT
I.DSXD=7		;A TRANSMIT DATA INTERRUPT
I.DSXS=6		;A TRANSMIT STATUS INTERRUPT
;
;BITS IN XMIT STATUS REGISTER & RECEIVE REG.
;
DS.DTR=000440		;BOTH XMT & RCV REG.
DS.ZAP=170000		;CLEAR ALL OVERRUN FLAGS
DS.XGO=DS.DTR+<<I.DSXD/2>*4>+1	;REQUEST TO SEND
DS.RGO=B11!B10!DS.DTR!<<I.DSRD/2>*4>+1	;RECEIVE
;
;BITS IN TRANSMIT STATUS REGISTER
;
;	B15		; NOT USED
;	B14		; XMIT BIT OVERRUN
;	B13		; XMIT CHAR OVERRUN
;	B12		; CLEAR TO SEND FLAG
;	B11		; NOT USED
;	B10		; NOT USED
;	B9		; CLEAR TO SEND
;	B8		; DATA TERM READY
;	B7		; XMIT CHAR DONE
;	B6		; DATA SET READY
;	B5		; CODE SIZE 2
;	B4		; CODE SIZE 1
;	B3		; PRIORITY REQUEST 2
;	B2		; PRIORITY REQUEST 1
;	B1		; IDLE
;	B0		; REQUEST TO SEND
;
;BITS IN RECEIVE STATUS REGISTER
;
;	B15		; RING FLAG
;	B14		; REC BIT OVERRUN
;	B13		; REC CHAR OVERRUN
;	B12		; LINE SIGNAL FLAG
;	B11		; SYN STATE 2
;	B10		; SYN STATE 1
;	B9		; LINE SIGNAL
;	B8		; DATA TERMINAL READY
;	B7		; REC CHAR DONE
;	B6		; DATA SET READY
;	B5		; CODE SIZE 2
;	B4		; CODE SIZE 1
;	B3		; PRIORITY REQUEST 2
;	B2		; PRIORITY REQUEST 1
;	B1		; RING ALLOW
;	B0		; RECEIVE
.PAGE
.SBTTL		DTE20 - DECSYSTEM 20(10)/PDP-11 INTERPROCESSOR INTERFACE
;
DLYCNT	= 0		;DELAY COUNTER
	BUSA17	= B15		;UNIBUS ADDRESS BIT 17
	BUSA16	= B14		;UNIBUS ADDRESS BIT 16
	DLYMSK	= 37777		;DELAY COUNT FIELD
DEXWD3	= 2		;DEPOSIT/EXAMINE WORD 3
DEXWD2	= 4		;DEPOSIT/EXAMINE WORD 2
DEXWD1	= 6		;DEPOSIT/EXAMINE WORD 1
TENAD1	= 10		;KL-10 MEMORY ADDRESS 1
TENAD2	= 12		;KL-10 MEMORY ADDRESS 2
TO10BC	= 14		;TO -10 BYTE (WORD) COUNT
TO11BC	= 16		;TO -11 BYTE (WORD) COUNT
	TO11IB	= B15		;INTERRUPT BOTH SIDES WHEN DONE
	TO11BM	= B13		;TO -11 BYTE MODE
	TO11CM	= 7777		;BYTE (WORD) COUNT
TO10AD	= 20		;TO -10 ADDRESS
TO11AD	= 22		;TO -11 ADDRESS
TO10DT	= 24		;TO -10 DATA WORD
TO11DT	= 26		;TO -11 DATA WORD
DIAG1	= 30		;DIAGNOSTIC CONTROL REGISTER 1
DIAG2	= 32		;DIAGNOSTIC CONTROL REGISTER 2
	DRESET	= B6		;(W) DTE20 RESET
CSTAT	= 34		;CONTROL STATUS REGISTER
	TO10DN	= B15		;(R) TO -10 TRANSFER DONE
	DON10C	= B14		;(W) CLEAR TO -10 DONE
	TO10ER	= B13		;(R) TO -10 TRANSFER ERROR
	ERR10C	= B12		;(W) CLEAR TO -10 TRANSFER ERROR
	TO11DB	= B11		;(R) TO -11 DOORBELL
	INT11S	= TO11DB	;(W) REQUEST INTERRUPT
	INT11C	= B10		;(W) CLEAR TO -11 DOORBELL
	MPE11	= B9		;(R) -11 PARITY ERROR
	TO10DB	= B8		;(R/W) TO -10 DOORBELL
	TO11DN	= B7		;(R) TO -11 TRANSFER DONE
	DON11C	= B6		;(W) CLEAR TO -11 DONE
	INTRON	= B5		;(W) ENABLE FROM -10 INTERRUPTS
	BPARER	= B4		;(R) EBUS PARITY ERROR
	INTROF	= B3		;(W) DISABLE FROM -10 INTERRUPTS
	RM	= INTROF	;(R) RESTRICTED MODE
	DEXDON	= B2		;(R) DEPOSIT/EXAMINE DONE
	TO11ER	= B1		;(R) TO -11 TRANSFER ERROR
	ERR11S	= TO11ER	;(W) SET TO -11 ERROR
	ERR11C	= B0		;(W) CLEAR TO -11 TRANSFER ERROR
	INTSON	= ERR11C	;(R) INTERRUPTS ARE ENABLED
DIAG3	= 36		;DIAGNOSTIC CONTROL REGISTER 3
	TO10BM	= B0		;(W) TO -10 BYTE MODE
.PAGE
.SBTTL		DU11 - SYNCHRONOUS LINE CONTROLLER
.PAGE
.SBTTL		DUP11 - SYNCHRONOUS LINE INTERFACE WITH CRC
;
DUP.LVL	= 6
;
;;;;	DUPSTS = FLOATING
;
DUPCRS = 0	;RECEIVER STATUS AND CONTROL REGISTER
	NAMEBT	DUPRCS,0,<DUPDSA,DUPRNG,DUPCTS,DUPCAR,DUPACT,DUP2RC>
	NAMEBT	,,<DUPDSR,DUPSSY,DUPRDN,DUPRIE,DUPDIE,DUPRCE>
	NAMEBT	,,<DUP2TX,DUPRTS,DUPDTR,DUPDSB>
				;
			.REPT	0
		DUPDSA	- DATA SET CHANGE A	RO
		DUPRNG	- RING INDICATOR	RO
		DUPCTS	- CLEAR TO SEND		RO
		DUPCAR	- CARRIER		RO
		DUPACT	- ACTIVE		RM
		DUP2RC	- SECONDARY RECEIVE DATA RO
		DUPDSR	- DATA SET READY	RO
		DUPSSY	- STRIP SYNCH		RW
	
		DUPRDN	- RECEIVE DONE		RO
		DUPRIE	- RECEIVER INTERRUPT ENABLE RW
		DUPDIE	- DATA SET INTERRUPT ENABLE RW
		DUPRCE	- RECEIVE ENABLE (CLEARS THE READ MOSTLY BITS) RW
		DUP2TX	- SECONDARY TRANSMIT	RW
		DUPRTS	- REQUEST TO SEND	RW
		DUPDTR	- DATA TERMINAL READY	RW
		DUPDSB	- DATA SET CHANGE B	RO
			.ENDR
DUPRDB = 2		;RECEIVE DATA BUFFER
	NAMEBT	DUPRDB,0,<DUPRER,DUPROV,,DUPRCR,,DUPRAB,DUPREM,DUPRSM>
	DUPRDT	= 377			;RECEIVED DATA BUFFER
			.REPT	0
		DUPRER	- RECEIVER ERROR	RO
		DUPROV	- RECEIVER OVERRUN	RO
			- RESERVED
		DUPRCR	- RCRC ERROR+ZERO	RO
			- RESERVED
		DUPRAB	- RECEIVED ABORT	RW
		DUPREM	- END OF REC'D MSG	RM
		DUPRSM	- START OF REC'D MSG	RM
			.ENDR
DUPPSR = DUPRDB		;PARAMETER STATUS REGISTER
	NAMEBT	DUPPSR,0,<DUPPDM,,,DUPP2M,,,DUPPIC,>
	DUPP2S	= 377		;SECONDARY STATION ADDRESS OR REC SYNCH REG
			.REPT	0
		DUPPDM	- DEC MODE (BYTE MODE)		WO
			- RESERVED
			- RESERVED
		DUPP2M	- SENCONDARY MODE SELECT	WO
			- RESERVED
			- RESERVED
		DUPPIC	- INHIBIT CRC COMPUTATION	WO
			.ENDR
DUPTCS = 4		;TRANSMITTER STATUS REGISTER
	NAMEBT	DUPTCS,0,<DUPTDL,DUPTMT,DUPTMC,DUPTM1,DUPTM0>
	NAMEBT	,,<DUPTMI,DUPTAC,DUPTRS,DUPTDN,DUPTIE,,DUPTSN,DUPTHD,,,>
			.REPT	0
		DUPTDL	- TRANSMIT DATA LATE	RM
		DUPTMT	- MAINTENANCE TRANSLATE	RO
		DUPTMC	- MAINTENANCE CLOCK	RW
		DUPTM1	- MAINTENANCE MODE SELECT RW
		DUPTM0	- 
		DUPTMI	- MAINTENANCE INPUT	RW
		DUPTAC	- TRANSMITTER ACTIVE	RO
		DUPTRS	- DEVICE RESET		WO
		DUPTDN	- TRANSMIT DONE		RM
		DUPTIE	- TRANSMITTER INTERRUPT ENABLE RW
			- RESERVED
		DUPTSN	- SEND			RW
		DUPTHD	- HALF DUPLEX		RW
			- RESERVED
			- RESERVED
			- RESERVED
			.ENDR
DUPTDB = 6		;TRANSMITTER DATA BUFFER
		NAMEBT	DUPTDB,0,<,DUPXCI,,DUPXCO,DUPXMT,DUPXAB,DUPXEM,DUPXSM>
		DUPXDB	= 377		;TRANSMITTER DATA BUFFER BYTE
			.REPT	0
			- RESERVED
		DUPXCI	- MAINTENANCE CRC INPUT	RO
			- RESERVED
		DUPXCO	- MAINTENANCE CRC OUTPUT RO
		DUPXMT	- MAINTENANCE TIMER	RO
		DUPXAB	- TRANSMIT ABORT	RW
		DUPXEM	- TRANSMIT END OF MSG	RW
		DUPXSM	- TRANSMIT STRAT OF MSG	RW
			.ENDR
.PAGE
.SBTTL		DZ11 - ASYNCHRONOUS SERIAL LINE MULTIPLEXER
;
; DZ11 CONTROL STATUS REGISTER (CSR) FLAGS
;
DZ.CLR=	000020				;MASTER CLEAR
DZ.SCN=	000040				;SCAN ENABLE (ENABLE RCV & XMT)
DZ.RIE=	000100				;RECEIVE INTERUPT ENABLE
DZ.SAE=	010000				;SILO ALARM ENABLE
DZ.TIE=	040000				;TRANSMIT INTERUPT ENABLE
DZ.INI=	DZ.SCN!DZ.RIE!DZ.TIE!DZ.SAE	;INITIAL VALUE FOR CSR
 
 
;
; DZ11 LINE PARAMETER REGISTER (LPR) FLAGS
;
DZ.RCV=	010000				;RCV ON IN LPR
.PAGE
.SBTTL		EIA PIN DEFINITIONS
;
;	1	PROTECTIVE GROUND
;	2	TRANSMITTED DATA
;	3	RECEIVED DATA
;	4	REQUEST TO SEND
;	5	CLEAR TO SEND
;	6	DATA SET READY
;	7	SIGNAL GROUND
;	8	RECEIVED LINE SIGNAL DECTECTOR
;	9	*
;	10	*
;	11	*
;	12	*
;	13	*
;	14	*
;	15	*
;	16	*
;	17	RECEIVED SIGNAL ELEMENT TIMING
;	18	*
;	19	*
;	20	DATA TERMINAL READY
;	21	SIGNAL QUALITY DETECTOR
;	22	RING INDICATOR
;	23	*
;	24	TRANSMIT SIGNAL ELEMENT TIMING
;	25	*
.PAGE
.SBTTL		KG11 - COMMUNICATIONS ARITHMETIC PROCESSOR
;
KG.STS = 170700
	KG.DNE=200	;CALCULATION DONE
	KG.SEN=100	;NOT SINGLE CYCLE
	KG.STP=040	;STEP
	KG.CLR=020	;CLEAR
	KG.DDB=010	;WORD MODE
	;	007	;TYPE OF CALCULATION
	KG.CRC=001	; 1 = CRC-16
	KG.LRC=003	; 3 = LRC-16
	KG.CCI=005	; 5 = CRC-CCITT
KG.INI=	KG.SEN!KG.CLR!KG.CRC
KGBCC = 2
KGDATA = 4
;
.MACRO	KGLOAD	X,MODE
	Z=101
	    .IF NB MODE
	.IIF IDN <MODE>,<WORD>,Z=Z!KG.DDB	;SET WORD MODE
	.IIF IDN <MODE>,<BYTE>,Z=Z&<^CKG.DDB>
	    .ENDC;.IF NB MODE
	    .IF IDN <#0>,<X>
	Z=Z!KG.CLR
	    .IFF
	MOV	#133,(R4)		;CLEAN OUT KG11
	MOV	X,KGDATA(R4)		;LOAD WITH DATA  ( X )
	    .ENDC ;IDN <#0>,<X>
	MOV	#Z,(R4)		;AND SET CRC MODE
.ENDM	KGLOAD
.PAGE
.SBTTL		KT11 - MEMORY MANAGEMENT MODULE
;
.MACRO	MMNAM1	MODE,TYPE,SPACE,NUMB
	MODE'SPACE'S'TYPE'R'NUMB	= $MMADR
	$MMADR	= $MMADR + 2
.ENDM	MMNAM1
;
.MACRO	MMNAM2	MODE,BASE
	$MMADR	= BASE
	.IRPC	TYPE,<DA>
	  .IRPC	SPACE,<ID>
	    $$ = 0
	    .REPT 8.
	      MMNAM1	MODE,TYPE,SPACE,\$$
	      $$ = $$ + 1
	    .ENDR ;8.
	  .ENDR	;SPACE
	.ENDR	;TYPE
.ENDM	MMNAM2
;
;
;
; MEMORY MANAGEMENT STATUS REGISTER BLOCK
;	ASTERISK (*) DENOTES THE 11/34 MEMORY MANAGEMENT SUBSET
;
	MMGSR0	= 177572	;MEM MGT STATUS REGISTER	*
	NAMEBT	MMGSR0,0,<MG.ANR,MG.APL,MG.ARO,MG.TMM,,>
	NAMEBT	,,<MG.EMT,MG.MNT,MG.IDN,MG.MD1,MG.MD0>
	NAMEBT	,,<MG.DAD,MG.PG2,MG.PG1,MG.PG0,MG.ENB>
		.REPT	0
		MG.ANR - ABORT, NON-RESIDENT		*
		MG.APL - ABORT, PAGE LENGTH		*
		MG.ARO - ABORT, READ ONLY		*
		MG.TMM - ABORT, TRAP ON MEM MGT
		MG.XXX - UNUSED
		MG.XXX - UNUSED
		MG.EMT - ENABLE MEM MGT TRAP
		MG.MNT - MAINTENANCE MODE		*
		MG.IDN - INSTRUCTION DONE
		MG.MD1 - MODE, BIT 1			*
		MG.MD0 - MODE, BIT 0			*
		MG.DAD - D ADDRESS SPACE SELECTED
		MG.PG2 - PAGE SELECTED, BIT 2		*
		MG.PG1 - PAGE SELECTED, BIT 1		*
		MG.PG0 - PAGE SELECTED, BIT 0		*
		MG.ENB - ENABLE MEM MGT			*
		.ENDR ;TEXT
				;
	MMGSR1	= 177574	;GPR MODIFICATION RECORD
				;
	MMGSR2	= 177576	;VIRTUAL ADDRESS REGISTER	*
				;
	MMGSR3	= 172516	;
	NAMEBT	MMGSR3,4,<MG.KDS,MG.SDS,MG.UDS>
				;
;
; DEFINE NAMES FOR THE PAGE ADDRESS AND DESCRIPTOR REGISTERS
;
	MMNAM2	U,177600	;USER MODE MEM MGT		*
;;;;	MMNAM2	S,172200	;SUPERVISOR MODE MEM MGT (NOT FOR 11/34)
	MMNAM2	K,172300	;KERNEL MODE MEM MGT		*
;
; PAGE DESCRIPTOR REGISTER FIELD DEFINITIONS
;
	NAMEBT	PDR,0,<,PD.PL6,PD.PL5,PD.PL4,PD.PL3,PD.PL2,PD.PL1,PD.PL0>
	NAMEBT	,,<PD.A,PD.W,,,PD.ED,PD.AC2,PD.AC1,PD.AC0>
	FIELD	PD.PLF,PD.PL6,PD.PL0
	FIELD	PD.ACF,PD.AC2,PD.AC0
;
; VIRTUAL ADDRESS DEFINITIONS
;
	BSFACT	= 100	;BIAS FACTOR, NUMBER OF BYTES PER BLOCK
	.IRP	X,<0,1,2,3,4,5,6,7>
	PAGE'X	= X*20000	;BASE ADDRESS REACHED THROUGH APR'X
	PAGE'X'B	= X*200	;MAPPING BIAS FOR VIRTUAL=PHYSICAL
	.ENDR	;IRP X
	PAGE7B	= 7600	;PAGE 7 BIAS (I/O PAGE) HAS A SPECIAL VALUE
.PAGE
.SBTTL		KW11 - LINE TIME CLOCK
;
;KW11 LINE FREQUENCY CLOCK DEFINITIONS
;
.IF DF FT.87S
CLKLVL=	6		; DN87 USES STANDARD PRIORITY LEVEL
.IFF
CLKLVL=	4		; CLOCK INTERRUPT PRIORITY LEVEL
.ENDC
CLKVEC=	100		; CLOCK VECTOR
;
CLKWRD = 177546		; CLOCK STATUS WORD
;
	KW.INE=B6	; ENABLE INTERRUPTS
	CLKENB=B6	; ENABLE INTERRUPTS
	KW.TIC=B7	; CLOCK MONITOR TOGGLE (CLEARED BY PROGRAM)
.PAGE
.SBTTL		LP11 - LINE PRINTER CONTROLLER
;
LE.LVL=	4		; PROCESSOR LEVEL FOR LP11 INTERRUPTS
LE.VEC=	200		; VECTOR LOCATION
;
LE0STS = 177514	;STATUS REGISTER FOR 1ST LP11
	LE.STS=LE0STS
;
	LE.ERR=	B15	; ERROR BIT(POWER OFF, NO PAPER, GATE, TEMP, OFFLINE)
	LE.DNE=	B7	; READY FOR NEXT CHARACTER
	LE.INE=	B6	; INTERRUPT ENABLE
;
LE0DAT = 177516	;DATA REGISTER
	LE.DAT=LE0DAT
;
;
;FOR THE SECOND LP11
LE1STS = 177520
LE1DAT = 177522
.PAGE
.SBTTL		LP20 - LINEPRINTER CONTROLLER
;
; LP20 HARDWARE DEVICE REGISTER DEFINITIONS
;
LP.LVL	= 4		;BUS REQUEST PRIORITY
LP.VEC	= 754		;FIRST LP VECTOR
			;
LP0STS	= 175400	;LP20 UNIT 0 FIRST REGISTER BLOCK
			;
LPCSRA=0		;CONTROL AND STATUS REGISTER A
	NAMEBT	LPCSRA,0,<LP.ERR,LP.PGZ,LP.CHI,LP.VFR,LP.ONL,LP.DH>
	NAMEBT	,,<LP.RSE,LP.LOI,LP.DNE,LP.IE,LP.B17,LP.B16>
	NAMEBT	,,<LP.MD1,LP.MD0,LP.PEN,LP.GO>
			.REPT	0
		LP.ERR=	ERROR (R)
		LP.PGZ=	PAGE ZERO (R)
		LP.CHI=	UNDEFINED CHAR TRAPPED (R)
		LP.VFR=	VERT FORMAT UNIT READY (R)
		LP.ONL=	ONLINE (R)
		LP.DH=	DELIMITER HOLD (R-W)
		LP.RSE=	RESET ERRORS (W)
		LP.LOI=	LOCAL INITIALIZE (W)
		
		LP.DNE=	DONE (R)
		LP.IE=	INTERRUPT ENABLE (R-W)
		LP.B17=	HIGH ORDER BUS ADDRESS BITS (R-W)
		LP.B16=		"
		LP.MD1=	OPERATION MODE BITS (R-W)
		LP.MD0=		"
		LP.PEN=	PARITY CHECK INTERRUPT ENABLE (R-W)
		LP.GO=	START COMMAND (R-W)
			.ENDR
				;
			TSTMOD=	LP.MD0 * 1	;TEST MODE
			VFULOD=	LP.MD0 * 2	;VFU LOAD MODE
			RAMLOD=	LP.MD0 * 3	;LOAD TRANSLATION RAM
			LP.MDS=	LP.MD0 ! LP.MD1	;MODE BIT MASK
			LP.XAD=	LP.B17!LP.B16	;HIGH ORDER BUSADD BITS
			ENBGO=	LP.PEN!LP.IE!LP.GO ;ENABLES AND GO
				;
LPCSRB=2			;CONTROL AND STATUS REGISTER B
	NAMEBT	LPCRSA,0,<LP.DV,LP.180,LP.NRD,LP.PAR>
	NAMEBT	,,<LP.OPT,LP.TS2,LP.TS1,LP.TS0,LP.OFL,LP.VFE>
	NAMEBT	,,<LP.PER,LP.MPE,LP.RPE,LP.SYN,LP.DEM,LP.GOE>
				;
			.REPT	0
		LP.DV=	VALID DATA (R)
		LP.180=	PRINTER IS AN LA180 (R)
		LP.NRD=	LINE PRINTER NOT READY (R)
		LP.PAR=	LINE PRINTER PARITY (R)
		LP.OPT=	PRINTER HAS OPTICAL VFU (R)
		LP.TS2=	TEST MODE BITS (R-W)
		LP.TS1=		"
		LP.TS0=		"
		
		LP.OFL=	DEVICE NOT READY (R)
		LP.VFE=	CHANNEL TYPE ERROR (R)
		LP.PER=	VARIOUS PARITY ERRORS (R)
		LP.MPE=		"
		LP.RPE=		"
		LP.SYN=	SYNCH TIMEOUT (DATA LATE) (R)
		LP.DEM=	DEMAND TIMEOUT (PRINTER HANG) (R)
		LP.GOE=	GO ERROR (R-W)
			.ENDR
				;
LPBSAD=4			;BUS ADDRESS REGISTER (R-W)
				;
LPBCTR=6			;BYTE COUNT (2'S COMPLEMENT)
		; BITS	15-12	NOT USED
		;	11-0	BYTE COUNT (R-W)
		;
LPPCTR=10			;PAGE COUNTER
		; BITS	15-12	NOT USED
		;	11-0	PAGE COUNT (R-W)
		;
LPRAMD=12			;RAM DATA REGISTER
	NAMEBT	LPRAMD,0,<,,,LP.RP,LP.RIN,LP.RDL,LP.RTR,LP.RPI>
		RAMDAT = LP.RP - 1	;MASK FOR WRITABLE RAM BITS
		SLEW = 20	;"SLEW" FLAG FOR VFU
		; BITS	15-13	NOT USED
		;	12	RAM PARITY (R)
		;	11-0	RAM DATA (R-W)
		;
LPCBUF=14			;(BYTE) CHARACTER BUFFER REGISTER (R-W)
LPCCTR=15			;(BYTE) COLUMN COUNT REGISTER (R-W)
				;
LPTDAT=16			;(BYTE) PRINTER DATA REGISTER (R)
LPCKSM=17			;(BYTE) CHECKSUM REGISTER (R)
				;
LPRBSZ=20			;SIZE OF HARDWARE REGISTER BLOCK
.PAGE
.SBTTL		MM11-LP PARITY MEMORY
;
	MP.VEC=114
	MP.LVL=7
;
MP.REG=172100		;ADR OF PARITY REGISTER
;
	MP.ERR=100000	;ERROR BIT
			; BITS 11-5 ERROR ADDRESS
	MP.WWP=000004	;WRITE WRONG PARITY
	MP.ENB=000001	;ENABLE
.PAGE
.SBTTL		PA611 - TYPESET READER/PUNCH
;
P6.LVL=	7		; PROCESSOR LEVEL FOR PA611P INTERRUPTS
;
R6.LVL=	7		; PROCESSOR LEVEL FOR PA611R INTERRUPTS
.PAGE
.SBTTL		PC11 - PAPER TAPE READER/PUNCH INTERFACE
;
PR.LVL=	4		; PROCESSOR LEVEL FOR PC11 READER INTERRUPTS
PR.VEC=	70		; VECTOR FOR PC11 READER
PP.LVL=	4		; PROCESSOR LEVEL FOR PC11 PUNCH INTERRUPTS
PP.VEC=	74		; VECTOR FOR PC11 PUNCH
;
PP0STS = 177554	;STATUS REGISTER FOR 1ST PC11 PUNCH
PP.STS=	177554		; PUNCH STATUS REGISTER
;
	PP.ERR=	B15	; ERROR BIT (NO TAPE OR NO POWER)
	PP.RDY=	B7	; SET WHEN RREADY TO PUNCH A CHARACTER
	PP.INE=	B6	; INTERRUPT ENABLE
;
PP.DAT=	177556		; PUNCH BUFFER REGISTER
;
PR0STS = 177550		;STATUS REGISTER FOR 1ST PC11 READER
PR.STS=	177550		; READER STATUS REGISTER
;
	PR.ERR=	B15	; ERROR BIT (NO TAPE, NO POWER, OR OFF-LINE)
	PR.BSY=	B11	; SET WHEN A CHARACTER IS BEING READ
	PR.DNE=	B7	; CHARACTER IS AVAILABLE IN THE READER BUFFER
	PR.INE=	B6	; INTERRUPT ENABLE
	PR..RE=	B0	; READER ENABLE
;
PR.DAT=	177552		; READER BUFFER REGISTER
.PAGE
.SBTTL		TC11 - DECTAPE CONTROLLER
;
TC.VEC=	214			; TC11 INTERRUPT VECTOR ADDRESS
;
TC.LVL=	6			; TC11 PRIORITY LEVEL
;
TC.STS=	177340			; TC11 CONTROL AND STATUS REGISTER
;
	TC..EZ=	B15		; END ZONE
	TC.PAR=	B14		; PARITY ERROR
	TC.MTE=	B13		; MARK TRACK ERROR
	TC.ILO=	B12		; ILLEGAL OPERATION
	TC..SE=	B11		; SELECTION ERROR
	TC..BM=	B10		; BLOCK MISSED
	TC..DM=	B9		; DATA MISSED
	TC.NXM=	B8		; NON-EX MEM
	TC.UPS=	B7		; TAPE IS UP TO SPEED
	TC.CLK=	B6		; USED TO SIMULATE TIMING TRACK
	TC.MMT=	B5		; MAINT MARK TRACK
	TC.DT0=	B4		; DATA TRACK 0
	TC.DT1=	B3		; DATA TRACK 1
	TC.DT2=	B2		; DATA TRACK 2
	TC.D17=	B1		; EXTENDED DATA 17
	TC.D16=	B0		; EXTENDED DATA 16
;
TC.CMD=	177342			; TC11 COMMAND REGISTER
;
	TC.ERR=	B15		; ERROR
	TC..MM=	B13		; MAINT MODE
	TC..DI=	B12		; DELAY INHIBIT
	TC.REV=	B11		; SET = REVERSE MOTION; CLEAR = FORWARD MOTION
	TC.US0=	0		; SELECT UNIT 0
	TC.US1=	B8		; SELECT UNIT 1
	TC.US2=	B9		; SELECT UNIT 2
	TC.US3=	B9!B8		; SELECT UNIT 3
	TC.US4=	B10		; SELECT UNIT 4
	TC.US5=	B10!B8		; SELECT UNIT 5
	TC.US6=	B10!B9		; SELECT UNIT 6
	TC.US7=	B10!B9!B8	; SELECT UNIT 7
	TC.RDY=	B7		; READY
	TC.INE=	B6		; INTERRUPT ENABLE
	TC.A17=	B5		; EXTENDED MEM BIT BA17
	TC.A16=	B4		; EXTENDED MEM BIT BA16
	TC.SAT=	0		; STOP ALL TAPE MOTION
	TC.RMT=	B1		; FINDS MARK TRACK CODE
	TC..RD=	B2		; READ
	TC.RDA=	B2!B1		; READ ALL
	TC.SST=	B3		; STOP ALL TAPE MOTION IN SEL'D TRANSPORT ONLY
	TC.WTM=	B3!B1		; WRITE TIMING AND MARK TRACK
	TC..WR=	B3!B2		; WRITE
	TC.WRA=	B3!B2!B1	; WRITE ALL
;
TC.WCR=	177344			; TC11 WORD COUNT REGISTER
;
TC.BAR=	177346			; TC11 BUS ADDRESS REGISTER
;
TC.DAT=	177350			; TC11 DATA REGISTER
.PAGE
.SBTTL		TM11 - MAGNETIC TAPE CONTROLLER
;
TM.VEC=	224			; TM11 VECTOR ADDRESS
;
TM.LVL=	5			; TM11 PRIORITY LEVEL
;
TM.STS=	172520			; STATUS REGISTER
;
	TM..IC=	B15		; ILLEGAL COMMAND
	TM.EOF=	B14		; END OF FILE
	TM.CRE=	B13		; CYCLICAL REDUNDANCY
	TM.PAE=	B12		; PARITY ERROR
	TM.BGL=	B11		; BUS GRANT LATE
	TM.EOT=	B10		; END OF TAPE
	TM.RLE=	B9		; RECORD LENGTH ERROR
	TM.BTE=	B8		; BAD TAPE ERROR
	TM.NXM=	B7		; NON-EXISTENT MEMORY
	TM.SLR=	B6		; SELECT REMOTE
	TM.BOT=	B5		; BEGINNING OF TAPE
	TM.7CH=	B4		; SEVEN CHANNEL
	TM.TSD=	B3		; TAPE SETTLE DOWN
	TM.WRL=	B2		; WRITE LOCK
	TM.RWS=	B1		; REWIND STATUS
	TM.TUR=	B0		; TAPE UNIT READY
;
TM.MTC=	172522			; COMMAND REGISTER
;
	TM.ERR=	B15		; ERROR
	TM.D72=	0		; 200 BPI 7 CHANNEL
	TM.D75=	B13		; 556 BPI 7 CHANNEL
	TM.D78=	B14		; 800 PBI 7 CHANNEL
	TM.D98=	B14!B13		; 800 BPI 9 CHANNEL
	TM..PC=	B12		; POWER CLEAR
	TM..LP=	B11		; LATERAL PARITY
	TM..US=	B10!B9!B8	; UNIT SELECT FIELD
	TM.US0=	0		; SELECT UNIT 0
	TM.US1=	B8		; SELECT UNIT 1
	TM.US2=	B9		; SELECT UNIT 2
	TM.US3=	B8!B9		; SELECT UNIT 3
	TM.US4= B10		; SELECT UNIT 4
	TM.US5=	B10!B8		; SELECT UNIT 5
	TM.US6=	B10!B9		; SELECT UNIT 6
	TM.US7=	B10!B9!B8	; SELECT UNIT 7
	TM.CUR=	B7		; CU READY
	TM.INE=	B6		; INTERRUPT ENABLE
	TM.A17=	B5		; EXTENDED MEM BIT BA17
	TM.A16=	B4		; EXTENDED MEM BIT BA16
	TM.OFL=	0		; OFF-LINE
	TM..RD=	B1		; READ
	TM..WR=	B2		; WRITE
	TM.WEF=	B1!B2		; WRITE EOF
	TM..SF=	B3		; SPACE FORWARD
	TM..SR=	B3!B1		; SPACE REVERSE
	TM.WEG=	B3!B2		; WRITE WITH EXTENDED GAP
	TM.REW=	B3!B2!B1	; REWIND
	TM..GO=	B0		; GO
;
TM.BCR=	172524			; BYTE COUNT REGISTER
;
TM.BAR=	172526			; BYTE ADDRESS REGISTER
;
TM.DAT=	172530			; DATA BUFFER
;
TM.RDL=	172532			; TU 10 READ LINES
.PAGE
.SBTTL	END OF DEVICE DEFINITIONS
;
; HERE AGAIN RESIDE THE HIDDEN DEBUGGING AND OTHER SPECIAL MACROS
;    WHICH ARE HIDDEN IN THE INTEREST OF SAVING ASSEMBLY TIME RESOURCES
;    AND LARGE AMOUNTS OF PAPER IN LISTING
	.NLIST
	.REPT	0
	.SBTTL	DEBUGGING MACROS - CREATED LABELS
;
;
;	CODE  BY LAD 10/75
;
;
;
;	MACROS FOR CREATED LABELS
;
.MACRO	C.LAB.	QQI,QQT
QQT'QQI'$:
.ENDM	C.LAB.
;
.MACRO C..LAB	QI
	    .IF LT CL.TAG
	C.LAB.	\.CLAB.,CL
	    .IFF
	C.LAB.	\.CLAB.,\CL.TAG
	    .ENDC ;LT CL.TAG
	.IIF NB <QI>	QI=.CLAB.
	.CLAB.=.CLAB.+1
.ENDM	C..LAB
.CLAB.=1
.IIF NDF CL.TAG,CL.TAG=1
;
;
;	MACRO FOR MAKING BRANCHS TO CREATED LABELS
;
.MACRO	CLBR	QINDX,QCOND,QTAG
	  .IF NB QTAG
	    .IF B <QCOND>
	BR	QTAG'QINDX'$
	    .IFF ;B <QCOND>
	B'QCOND	QTAG'QINDX'$
	    .ENDC ;B <QCOND>
	  .IFF ;NB QTAG
	    .IF LT CL.TAG
	CLBR	QINDX,QCOND,CL
	    .IFF ;LT CL.TAG
	CLBR	QINDX,QCOND,\CL.TAG
	    .ENDC ;LT CL.TAG
	  .ENDC ;NB QTAG
.ENDM	CLBR
;
;
.MACRO	SET.CD	QCD
	S.....=S..'QCD
.ENDM	SET.CD
;
S.....=0
.PAGE
.SBTTL	DEBUGGING MACROS - ASSERT
;
; TO USE ASSERT MACRO
;
;   IN THE FOLLOWING DISCOURSE, ELEMENTS QUOTED (E.G. "SET")
;   ARE LITERALS AND MUST BE USED LITERALLY - OTHER ELEMENTS
;   (E.G. VALUE) ARE PROGRAMMER SPECIFIABLE - "ASSERT" ALWAYS
;   REFERS TO THE MACRO INVOCATION, QUOTED OR NOT
;
; TO ENFORCE A RANGE OF VALUES
;		ASSERT	THING "BETWEEN" VALUE1 VALUE2
;
; TO ENFORCE BITS CLEARED
;		ASSERT	BITS "CLEAR" "IN" THING
;
; TO ENFORCE BITS SET
;		ASSERT	BITS "SET" "IN" THING
;*** IN THIS CASE THING MAY NOT HAVE A R6 (STACK) TYPE MODIFICATION
;*** IE, ON(SP) OR (SP)+ ETC
;
; TO ENFORCE  CONDITION (CONDITION IS THE SUFFIX
;    OF A LEGAL BRANCH INSTRUCTION, E.G. LO, LOS, GE, ETC)
;		ASSERT	VALUE1 CONDITION VALUE2
; OR		ASSERT	CONDITION VALUE
; OR
;		ASSERT	CONDITION
;
; TO ENFORCE LINK TO CHUNK BOUNDARY
;		ASSERT	"CHUNK" VALUE
;
;
.PAGE
.IIF NDF FTASRT,FTASRT=0
	    .IF NE FTASRT
.MACRO	ASSERT	FRST,SCND,THRD,FRTH
	    .IF NB <FRTH>
	    .IF IDN <THRD>,<IN>
	    .IF IDN <SCND>,<CLEAR>
	BIT	FRST,FRTH	;ASSERT - ALL BITS OF FRST CLEAR IN FRTH ?
	BEQ	.+4		;YES
	TRAP	S.....		;NO
	    .IFF ;IDN <CLEAR>
	    .IF IDN <SCND>,<SET>
	MOV	FRTH,-(P)	;ASSERT - ANY OF FRST SET IN FRTH ?
	COM	(P)		;COMPLEMENT AND CHECK FOR CLEAR (ABOVE)
	ASSERT	(P)+ CLEAR IN FRST
	    .ENDC ;IDN <SCND><SET>
	    .ENDC ;IDN <SCND><CLEAR>
	    .IFF ;IDN <THRD><IN>
	CMP	FRST,THRD	;ASSERT - RANGE CHECK
	CLBR	\.CLAB.,LO	;FSRT MUST BE HIS AS THRD
	CMP	FRST,FRTH	;  AND LOS AS FRTH
	BLOS	.+4		;
	C..LAB			;
	TRAP	S.....		; OR YOU WILL TRAP
	    .ENDC ;IDN <IN>
	    .IFF ;NB <FRTH>
	    .IF NB <THRD>
	CMP	FRST,THRD	;SINGLE ENDED CHECK - IS FRST SCND THRD
	B'SCND	.+4		;YES
	TRAP	S.....		;NO
	    .IFF ;NB <THRD>
	    .IF IDN <FRST>,<CHUNK>
	SET.CD	CNK		;BOUNDARY CHECK
	ASSERT	#CNKSIZ-1 CLEAR IN SCND
	    .IFF ;IDN<FRST><CHUNK>
				;SINGLE VALUED CONDITIONAL
	.IIF NB <SCND>,	TST	SCND
	B'FRST	.+4
	TRAP	S.....
	    .ENDC ;IDN <THRD><CHUNK>
	    .ENDC ;NB <THRD>
	    .ENDC ;NB <FRTH>
S.....=0
.ENDM	ASSERT
;
	    .IFF ;NE FTASRT
;
.MACRO ASSERT FRST,SCND,THRD,FRTH
.ENDM ASSERT
;
	    .ENDC ;NE FTASRT
.PAGE
	.SBTTL	DEBUGGING MACROS - CPU POKER
;	CODE  BY LAD 10/75
;
;	DEFINE THE CPU POKER QUEUE
;
.IIF NDF CP.SIZ,CP.SIZ=0	;DEFAULT IS TO FORGO RANDOM POKE
	    .IF NE CP.SIZ
	CP.SIZ=<CP.SIZ+37>&177740 ;ROUND UP CP.SIZ TO A 32. BYTE BOUND
.MACRO	MCPQUE
	CP.PTR:	.WORD	CP.QUE
	CP.QUE:	.BLKB	CP.SIZ
;
;	DO THE CPU POKE
;
;		LEAVE TRACE OF ACTIVITY
CPUQUE:	SAVE	<R1,R0>		;SAVE REGISTERS
	MOV	P,R1		;COPY STACK POINTER
	MOV	CP.PTR,R0	;GET ADDRESS IN QUEUE
	MOV	(R1)+,(R0)+	;COPY USER REGS 0-5 TO QUEUE
	MOV	(R1)+,(R0)+	;
	MOV	R2,(R0)+	;
	MOV	R3,(R0)+	;
	MOV	R4,(R0)+	;
	MOV	J,(R0)+		;
	TST	(R1)+		;SKIP JSR RETURN ADDRESS
	MOV	R1,(R0)+	;SAVE COPY OF ENTERING STACK POINTER
	MOV	PS,(R0)+	;SAVE PSW
	MOV	(R1)+,(R0)+	;SAVE 8 MORE STACK ENTRIES
	MOV	(R1)+,(R0)+	;
	MOV	(R1)+,(R0)+	;
	MOV	(R1)+,(R0)+	;
	MOV	(R1)+,(R0)+	;
	MOV	(R1)+,(R0)+	;
	MOV	(R1)+,(R0)+	;
	MOV	(R1)+,(R0)+	;
	CMP	R0,#CP.QUE+CP.SIZ ;CHECK FOR QUEUE WRAP AND WRAP IF NEED BE
	BLO	.+6		;
	MOV	#CP.QUE,R0	;
	MOV	R0,CP.PTR	;
	RESTORE <R0,R1>		;
	RTS	PC		;
.ENDM	MCPQUE
;
.MACRO	CCPQUE
	JSR	PC,CPUQUE	;CALL POKER
.ENDM	CCPQUE
	    .IFF ;NE CP.SIZ
.MACRO	MCPQUE
.ENDM	MCPQUE
;
.MACRO	CCPQUE
.ENDM	CCPQUE
	    .ENDC ;NE CP.SIZ
.PAGE
	.SBTTL	DEBUGGING MACROS - PROFILER
;	CODE  BY LAD 10/75
;
;
.IIF NDF FT.PFL,FT.PFL=0	;DEFAULT IS NO PROFILER CODE
;PRFL.H=HIGH ADR
;PRFL.L=LOW ADR
;PRFL.S=N	;2**N IS INTERVAL
;
;IS USED TO SET UP PROFILER (INTERVAL IS 2**N)
;
;PROFILE
;IS USED AT CLOCK OR OTHER INTERRUPT TO DO THE WORK
;
;PROFILE	BLOCK
;IS USED TO SET UP THE PROFILE BUFFER
;
	    .IF NE FT.PFL
	.IIF NDF PRFL.S,PRFL.S=10
	.IIF NDF PRFL.H,PRFL.H=60000
	.IIF NDF PRFL.L,PRFL.L=1000
	Z=PRFL.H-PRFL.L
	ZZ=PRFL.S
	.IF LT	Z
		Z=<<Z&77777>/2>!40000
		ZZ=ZZ-1
	.ENDC
	.REPT	ZZ
		Z=Z/2
	.ENDR
	PRFL.Z=1
	.REPT	20
		.IIF NE Z,PRFL.Z=PRFL.Z*2
		.IIF NE Z,Z=Z/2
	.ENDR
	    .ENDC ;NE FT.PFL
.PAGE
;	ACTIVITY PROFILER
;
	    .IF NE FT.PFL
.MACRO	PROFILE	Q,QQ
	    .IF B Q
	MOV	R0,-(P)
	MOV	QQ+2(P),R0
	CMP	R0,#PRFL.H
	BHIS	120$
	SUB	#PRFL.L,R0
	BLO	120$
	CLC
	ROR	R0
	.REPT	PRFL.S
		ASR	R0
	.ENDR
	ASL	R0
	INC	PRFL.B(R0)
120$:	MOV	(P)+,R0
	    .IFF ;B Q
.IIF IDN <Q>,<BLOCK>,PRFL.B:	.BLKW	PRFL.Z
	    .ENDC ;B Q
.ENDM	PROFILE
	    .IFF ;NE FT.PFL
.MACRO	PROFILE	Q,QQ
.ENDM	PROFILE
	    .ENDC ;NE FT.PFL
.PAGE
	.SBTTL	DEBUGGING MACROS - SINK
;	CODE  BY LAD 10/75
;
;
.IIF NDF FT.SNK,FT.SNK=0	;DON'T INCLUDE DATA SINK CODE
.IIF NDF FT.SOU,FT.SOU=0	;DON'T INCLUDE DATA SOURCE CODE
;
;USED TO CONDITIONALLY QUEUE CHUNKS (MSGS) TO SYNCHRONOUS GARBAGE COLLECTOR
;	IE., SINK J <#LBLK0,#LBLK1>
;	SINKS MSGS FOR LINES 0,1 ONLY
;
;	THE THIRD ARGUMENT IS WHERE TO CONTINUE WHEN DONE QUEUEING THE MSG
;	IF THIS ARG IS 'COPY', THE NEXT INTSRUCTION IN SEQ IS EXECUTED
;	AND A COPY (NOT THE ORIGINAL) IS QUEUED
;	IF THE ARG IS NULL, THE MACRO EXITS WITH A 'RTS	PC'
;
;SINK	STORE
;	IS USED TO DEFINE THE SINK QUEUE AND DUMP BUFFER
;
;
;SINK TTYDDB
;	IS USED TO DIRECT THE SINK DUMP TO A TTY
;
;
	    .IF NE FT.SNK
.MACRO	SINK	QJ,QQ,QC
	    .IF NB <QQ>
	SINK00	QJ,<QQ>,QC
	    .IFF ;NB <QQ>
	    .IF NB <QJ>
	    .IF IDN <QJ>,<STORE>
	SINK01
	SINK02
	SINK03
	    .IFF ;IDN <STORE>
	SINK10	QJ
	    .ENDC ;IDN <STORE>
	    .IFF ; NB <QJ>
	SINK00	,,QC
	    .ENDC ;NB <QJ>
	    .ENDC ;NB <QQ>
.ENDM	SINK
	    .IFF ;NE FT.SNK
.MACRO	SINK	QJ,QQ,QC
.ENDM	SINK
	    .ENDC ;NE FT.SNK
.PAGE
	    .IF NE FT.SNK
.MACRO	SINK00	QJ,QQ,QC
	    .IF NB <QJ>
	.IRP	Q,<QQ>
	CMP	QJ,#Q
	CLBR	\.CLAB.,EQ
	.ENDR
	CLBR	\<.CLAB.+1>
	C..LAB
	INC	#0	;COUNT SINKS
	    .ENDC ;NB <QJ>
	    .IF NB <QC>
	.IF IDN <QC>,<COPY>
		JSR	PC,CSNKIT
	.IFF ;IDN <COPY>
		JSR	PC,SINKIT
		BR	QC
	.ENDC ;IDN <COPY>
	    .IFF ;NB <QC>
	JMP	SINKIT
	    .ENDC ;NB <QC>
	C..LAB
.ENDM	SINK00
;
.MACRO	SINK01
;
SINK.Q:	.WORD	0	;SINK QUEUE HEAD
SINK.T:	.WORD	0	;SINK QUEUE TAIL
SINK.C:	.WORD	0	;SINK QUEUE LENGTH
SINK.0:	.WORD	0	;LAST DUMPED
SINK.S=^D234	;MAX LINE LENGTH
SINK.B:
	.REPT	SINK.S		; THE LINE BUFFER
		.BYTE	0
	.ENDR
	.WORD	0	;EXTRA WORD
.ENDM	SINK01
;
.MACRO	SINK02
CSNKIT:	SAVE <R0,R1,R2>
	MOV	R0,R1
	JSR	PC,ERSGET
	SAVE	<R0>
CSNK.T:	MOV	#CNKSIZ/2,R2
	MOV	(R1)+,(R0)+
	SOB	R2,.-2
	SUB	#CNKSIZ,R0
	SUB	#CNKSIZ,R1
	MOV	R0,R2
	MOV	(R1),R1
	BEQ	.+12
	JSR	PC,ERSGET
	MOV	R0,(R2)
	BR	CSNK.T
	RESTORE	<R0,R2,R1>
	JSR	PC,SINKIT
	RESTORE	<R0>
	RTS	PC
;
SINKIT:
	PIOFF	;SO SINK WORKS EVERYWHERE
	TST	SINK.C
	BLE	10$
	ADD	#CN.MLK,SINK.T
	MOV	R0,@SINK.T
	BR	15$
10$:	MOV	R0,SINK.Q
15$:	MOV	R0,SINK.T
	CLR	CN.MLK(R0)
	INC	SINK.C
	PION
	RTS	PC
.ENDM	SINK02
;
.MACRO	SINK03
	;CONVERT BYTE TO OCTAL AND INSERT IN BUFFER
OCT3:	JSR	PC,(PC)		;DO THIS TWICE
10$:	MOVB	(R0)+,R3
	BIC	#^C377,R3	;CLEAR SIGN EXTENSION
	MOV	#4,R2		;SET FIELD LENGTH
	BR	IN2OCT		;AND CONVERT
;
;
	;CONVERT WORD TO OCTAL AND INSERT IN THE BUFFER
OCT6:	MOV	(R0)+,R3
	MOV	#10,R2
;	BR	IN2OCT		; CONVERT
;
;
	;CONVERT TO OCTAL AND INSERT IN THE BUFFER
	;R2 IS FEILD LENGTH
	;R3 IS VALUE
	;ON RETURN R2 IS UNDEFINED VALUE, AND R3 IS UNCHANGED
IN2OCT:	MOV	R3,-(P)		;SAVE THE VALUE
	DEC	R2		;COUNT THIS DIGIT
	CLC			;CLEAR CARRY FOR
	ROR	R3		;LOGICAL RIGHT SHIFT
	ASR	R3
	ASR	R3
	BEQ	I2O.1
	JSR	PC,IN2OCT	;RECURSE IF MORE DIGITS
I2O.1:	DEC	R2		;FILL WITH BLANKS
	BMI	I2O.2
	MOVB	#40,(R4)+
	BR	I2O.1
I2O.2:	MOV	(P),R3		;RESTORE PREVIOUS VALUE
	BIC	#^C7,(P)	;CONVERT DIGIT TO ASCII
	BIS	#60,(P)
	MOVB	(P)+,(R4)+	;AND INSERT
	RTS	PC
;
;
	;CONVERT BYTE TO ASCII AND INSERT IN BUFFER
	;_ PREFIX IMPLIES >200
	;^ PREFIX IMPLIES BITS 5 AND 6 =0
ASC3:	MOVB	#40,R2
	JSR	PC,10$		;DO THIS TWICE
10$:	MOVB	R2,(R4)+
	MOVB	R2,(R4)
	MOVB	(R0)+,R3
	BPL	12$
	MOVB	#137,(R4)
	BIC	#^C177,R3
12$:	INC	R4
	MOVB	R2,(R4)
	CMPB	R3,R2
	BHIS	14$
	MOVB	#136,(R4)
	BIS	#100,R3
14$:	INC	R4
	MOVB	R3,(R4)+
	RTS	PC
;
;
;
	;DEQUEUE THE SUNK MSGS
;
DQSINK:	MOV	SINK.0,R0
	BNE	05$
	TST	SINK.C
	BGT	.+4
	RTS	PC
	PIOFF	;MUST INHIBIT INTERRUPTS TO DEQUEUE
	MOV	SINK.Q,R0
	MOV	CN.MLK(R0),SINK.Q
	DEC	SINK.C
	PION
	MOV	R0,SINK.0
05$:	MOV	R0,R1
	MOV	#SINK.B,R4
	CLR	-(P)
10$:	MOV	#40,(P)
	ADD	#20,R1
20$:	MOV	R1,SINK.0
	BIT	#CNKSIZ-1,R1	;IF LAST LOAD DUMP IT
	BEQ	29$
	MOV	R0,R2
	MOV	#10,R3
30$:	CMP	(R0)+,(R1)+
	BEQ	31$
	MOV	R2,R0
	BR	29$
31$:	SOB	R3,30$
	MOV	#52,(P)
	MOV	R2,R0
	BR	20$
29$:	MOV	R0,R3
	BIT	#CNKSIZ-1,R0
	BNE	.+6		;EXTRA LINE FEED IF NEW BLOCK (CHUNK)
	MOV	#15*400+12,(R4)+
	MOV	#6,R2		;CONVERT AND OUTPUT ADDRESS
	JSR	PC,IN2OCT
	MOVB	(P)+,(R4)+
	MOV	R0,-(P)
	MOV	#OCT6,-(P)
WOFMT:	JSR	PC,SNKFMT
	MOV	#OCT3,(P)
BOFMT:	JSR	PC,SNKFMT
	MOV	#ASC3,(P)
BAFMT:	JSR	PC,SNKFMT
	CMP	(P)+,(P)+
	CLRB	(R4)+
	MOV	SINK.0,R0
	BIT	#CNKSIZ-1,R0
	BNE	07$
	SUB	#CNKSIZ,R0
	MOV	(R0),SINK.0
	CLR	(R0)
	JSR	PC,FRECKS
	CLZ
07$:	RTS	PC
;
;
	;DO FORMATED OUTPUT OF Q WORD FOR SINK
SNKFMT:	CMPB	-1(R4),#12	;BETTER INSERT FILL FOR EXTRA LINES
	BNE	20$
	MOV	#7,R1
10$:	MOVB	#40,(R4)+
	SOB	R1,10$
20$:	MOV	4(SP),R0
	MOV	#10,R1		;FORMAT THE NEXT 8 WORDS
30$:	JSR	PC,@2(SP)
	SOB	R1,30$
	MOVB	#15,(R4)+
	MOVB	#12,(R4)+
NULFMT:	RTS	PC
.ENDM	SINK03
;
.MACRO	SINK09	QJ
	MOV	#'QJ,J
	BIT	#DS.ACT,(J)	;GOT TO WAIT  TILL TTY IS NOT BUSY
	BNE	.+22
	JSR	PC,DQSINK	;GET THE NEXT BUFFER LOAD FROM THE SINK
	BEQ	.+14
	MOV	#SINK.B,DB.STR(J)
	JSR	PC,XMTBEG	;IF THERE IS ONE START IT TYPING
.ENDM	SINK09
;
.MACRO	SINK10	QJ
	    .IF EQ LPTSNK
	SINK09	QJ
	    .IFF ;EQ LPTSNK
	MOV	SINK.0,J
	BIS	SINK.C,J
	BEQ	126$		;NOTHING TO DUMP
	MOV	#'QJ,J
	MOV	DB.HDW(J),R3
				;STEAL THE LINE PRINTER
	BIC	#100,(R3)
	CLR	DB.TIM(J)
120$:	BIT	#100200,(R3)
	BLE	126$		;JUST WAITING OUR TURN
121$:	MOV	#0,R4
	BNE	122$		;IF WE HAVE A BUFFER, JUST FEED THE PRINTER
	SAVE	<R3>
	JSR	PC,DQSINK	;GET A BUFFER
	BEQ	125$		;WASN'T ANY, SO GIVE THE PRINTER BACK
	RESTORE	<R3>
	MOV	#SINK.B,R4
	MOV	R4,121$+2
122$:	INC	121$+2
	CMPB	(R4),#12	;IF <LF>, MAY WANT TO CHANGE IT TO <FF>
	BNE	124$
123$:	DEC	#0
	BPL	124$
	MOV	#77,123$+2
	MOVB	#14,(R4)
124$:	MOVB	(R4),2(R3)
	BR	121$
125$:	RESTORE	<R3>
	MOVB	#-3,DB.TIM(J)
	BIS	#100,(R3)
126$:
	    .ENDC ;EQ LPTSNK
.ENDM	SINK10
	    .ENDC ;NE FT.SNK
.PAGE
;CLRCNK		ZEROS OUT A CHUNK
;
.MACRO	CLRCNK	QREG
	    .IF NE FT.SNK!FT.SOU
	MOV	#CNKSIZ/2,-(P)
	CLR	(QREG)+
	DEC	(P)
	BNE	.-4
	TST	(P)+
	SUB	#CNKSIZ,QREG
	    .IFF ;NE FT.SNK!FT.SOU
	CLR	(QREG)
	CLR	2(QREG)
	    .ENDC ;NE FT.SNK!FT.SOU
.ENDM	CLRCNK
.PAGE
	.SBTTL	DEBUGGING MACROS - SOURCE
;	CODE  BY LAD 10/75
;
;
;SOURCE	N,I,L,M,P
;
;WILL ORIGINATE N MSGS WITH A DELAY OF I SECONDS BETWEEN THEM
;OVER LINE (SCB) (RDE DEV) L
;THE MSG IS AT M
;AND THE PROCEDURE P IS CALLED TO SEND IT
;
.IIF NE FT.SOU,SOULAB=0
;
.MACRO	SOURCE	QN,QI,QL,QM,QP
	    .IF NE FT.SOU
	C.LAB.	\SOULAB,SOU
SOULAB=SOULAB+1
	TST	#'QN
100$:	BEQ	103$
	DEC	#'QI
101$:	BNE	103$
	MOV	#'QI,101$-2
	DEC	100$-2
.IIF NB	<QM>,	MOV	#'QM,R4
.IIF B <QM>,	MOV	#SOU.M,R4
	JSR	PC,ERSGET
	MOV	R0,-(P)
	MOV	(R4),R1
	ADD	#CN.NCT-CN.LEN,R1
	INC	R1
	ASR	R1
	CMP	(R0)+,(R0)+
102$:	MOV	(R4)+,(R0)+
	ADVCNK	R0 EXTEND
	SOB	R1,102$
	MOV	(P)+,R0
	    .IF IDN	<QP>,<DDQDAT>
	MOV	#'QL,SB
	    .IFF ;IDN DDQDAT
	    .IF IDN <QP>,<DDQBOO>
	MOV	#'QL,SB
	    .IFF ;IDN <DDQBOO>
	MOV	#'QL,J
	MOV	#SOH,R2
	    .ENDC ;IDN <DDQBOO>
	    .ENDC ;IDN <DDQDAT>
.IIF B <QP>,	JSR	PC,DDQ.01
.IIF NB <QP>,	JSR	PC,QP
103$:
	    .ENDC ;NE.FT.SOU
.ENDM	SOURCE
.PAGE
;SOUMSG	LAB,LEN,DDB,SCB,DDC,CNT,NCN,DATA
;
;DEFINES A DATA MESSAGE FOR THE SOURCE MACRO
;LAB IS THE MSG NAME
;THE OTHER ARGS ARE THE HEADER WORDS
;
;DATA IS <D,D,...>	WHERE D IS
;BYTE VALUE, <LENGTH,VALUE>
;IF LENGTH =1 VALUE IS BYTE
;IF LENGTH =2 VALUE IS WORD
;IF LENGTH >2 VALUE IS BYTE,BYTE+1,... WITH WRAPAROUND AT =177
;
.MACRO	SOUMSG	QLAB,QLEN,QDDB,QSCB,QDDC,QCNT,QNCN,QDAT
	    .IF NE FT.SOU
.IIF B <QLAB>,SOU.M:
.IIF NB <QLAB>,QLAB':
	.WORD	QLEN,0
	.WORD	QDDB,QSCB,QDDC,QCNT,QNCN,0
	.MACRO	X	QQA,QQB
	    .IF B <QQB>
	.BYTE	QQA
	    .IFF ;B <QQB>
		.IIF EQ QQA-1,	.BYTE	QQB
		.IF EQ QQA-2
			.EVEN
			.WORD	QQB
		.ENDC ;EQ QQA-2
		.IF GT QQA-2
			Z=QQB
			.REPT	QQA
				.BYTE	Z
				Z=Z+1
				.IIF GE Z-177,Z=QQB
			.ENDR
		.ENDC ;GT QQA-2
	.ENDC ;B <QQB>
	.ENDM	X
	.IRP	QQC,<QDAT>
		X	QQC
	.ENDM
	.EVEN
	    .ENDC ;NE FT.SOU
.ENDM	SOUMSG
.PAGE
	.SBTTL	QUEUE ACCESS AND CHUNK HANDLING MACROS
;
;
;	BY LAD 10/75
;
;
;
.MACRO	ADVCNK	QREG,QFUN
.IF B QFUN
	.IF IDN QREG,SB
		BIT	#CNKSIZ-1,SB
		BNE	1$
		MOV	-CNKSIZ(SB),SB
		TST	(SB)+
1$:
	.IFF
		JSR	PC,AVCK'QREG
	.ENDC ;IDN SB
.IFF
	.IF IDN <QFUN>,<EXTEND>
		JSR	PC,GTCK'QREG
	.IFF
		.IF IDN <QFUN>,<FREE>
			JSR	PC,FRCK'QREG
		.IFF
.ERROR	227;	ADVCNK	QREG QFUN	?????
		.ENDC ;IDN <FREE>
	.ENDC ;IDN EXTEND
.ENDC ;B QFUN
.ENDM	ADVCNK
;
;
;
;TO FETCH AN ENTRY FROM THE QUEUES
;
.MACRO	QUEGET	QQUE,QFAIL
	    .IF IDN <QQUE>,<TI>
	MOV	TI.TKR,R1
	CMP	R1,TI.PTR
	BEQ	QFAIL
	CMP	R1,#<TI.QUE+TI.SIZ>
	BLO	.+6
	MOV	#TI.QUE,R1
	MOVB	(R1)+,R0
	BIC	#^C<377>,R0
	MOVB	(R1)+,J
	BIC	#^C<377>,J
	ASL	J
	MOV	DLATAB-2(J),J
	MOV	R1,TI.TKR
	    .IFF ;IDN <TI>
.MACRO	Q..GET	QREG,QFLAG
	CMP	QQUE'.TKR,QQUE'.PTR
	BEQ	QFAIL
	PIOFF
	CMP	QQUE'.TKR,#<QQUE'.QUE+QQUE'.SIZ>
	BLO	.+10
	MOV	#QQUE'.QUE,QQUE'.TKR
	MOV	@QQUE'.TKR,QREG
	ADD	#2,QQUE'.TKR
	BIC	#QFLAG,(QREG)
	PION
.ENDM	Q..GET
.IIF IDN <QQUE>,<NC>,	Q..GET	SB,SBF.NQ
.IIF IDN <QQUE>,<DV>,	Q..GET	J,DS.QUE
.IIF IDN <QQUE>,<QO>,	Q..GET	J,LS..XQ
.IIF IDN <QQUE>,<QI>,	Q..GET	J,LS..RQ
	    .ENDC ;IDN <TI>
.ENDM	QUEGET
.PAGE
;TO INSERT AN ENTRY ON THE QUEUES
;
.MACRO	QUEPUT	QQUE,QPROC
	    .IF IDN <QQUE>,<TI>
	MOV	TI.PTR,R0
	CMP	R0,#<TI.QUE+TI.SIZ>
	BLO	.+6
	MOV	#TI.QUE,R0
	MOVB	R1,(R0)+
	MOV	DB.OLA(J),R1
	ASR	R1
	MOVB	R1,(R0)+
	CMP	R0,TI.TKR
	BEQ	.+6
	MOV	R0,TI.PTR
	    .IFF
.MACRO	Q..PUT	QREG,QFLAG,QQFAIL
.IIF IDN <QPROC>,<CODE>,QQUE'.PUT:
;
	PIOFF
	BIT	#QFLAG,(QREG)
	BNE	QQFAIL
	BIS	#QFLAG,(QREG)
	CMP	QQUE'.PTR,#<QQUE'.QUE+QQUE'.SIZ>
	BLO	.+10
	MOV	#QQUE'.QUE,QQUE'.PTR
	MOV	QREG,@QQUE'.PTR
	ADD	#2,QQUE'.PTR
;	ASSERT	QQUE'.PTR NE QQUE'.TKR
QQFAIL:	PION
.IIF IDN <QPROC>,<CODE>	RTS PC
.ENDM	Q..PUT
;
.IIF IDN <QQUE>,<NC>	Q..PUT	SB,SBF.NQ,QPROC
	    .IF IDN <QQUE>,<QO>
	    .IF IDN <QPROC>,<CODE>
	Q..PUT	J,LS..XQ,10$
	    .IFF
	JSR	PC,QO.PUT
	    .ENDC ;IDN <CODE>
	    .ENDC ;IDN <R0>
	    .IF IDN <QQUE>,<QI>
	    .IF IDN <QPROC>,<CODE>
	Q..PUT	J,LS..RQ,10$
	    .IFF
	JSR	PC,QI.PUT
	    .ENDC ;IDN <CODE>
	    .ENDC ;IDN <QI>
.IIF IDN <QQUE>,<DV>	Q..PUT	J,DS.QUE,QPROC
	    .ENDC ;IDN <TI>
.ENDM	QUEPUT
.PAGE
	.SBTTL	DDCMP HEADER DEBUGGING LOG
;
;	CODE  BY LAD	10/75
;
	    .IF DF DMPHDR
;
.IIF NDF DMPHIN,DMPHIN=DMPHDR	;NUMBER OF INPUT HEADERS TO COLLECT
.IIF NDF DMPHOU,DMPHOU=0	;NUMBER OF OUTPUT HEADERS TO COLLECT
.IIF NDF DMPHLN,DMPHLN=LBLK0	;LINE TO MONITOR
;
.MACRO	HDRDMP	QIO,QLINE,QN
;
	    .IF IDN <QIO>,<STORE>
;
ICHK.B:	.BLKW	DMPHDR*4
ICHK.E:	.WORD	ICHK.B
;
	    .IFF ;IDN<STORE>
;
	CMP	J,#QLINE
QIO'CHK.L=.-2
	BNE	104$
	TST	#QN
QIO'CHK.C=.-2
	BEQ	104$
.IIF IDN <QIO>,<O>,	SAVE	<R1>
	MOV	ICHK.E,R1
	CMP	#ICHK.E,R1
	BHI	102$
	MOV	#ICHK.B,R1
102$:
	    .IF IDN <QIO>,<O>
	SUB	#10,R0
	    .IFF ;IDN <O>
	ADD	J,R0
	    .ENDC ;IDN <O>
	MOV	(R0)+,(R1)+
	MOV	(R0)+,(R1)+
	MOV	(R0)+,(R1)+
	MOV	(R0)+,(R1)+
	DEC	QIO'CHK.C
	BNE	103$
	MOV	#ICHK.B,R1
103$:	MOV	R1,ICHK.E
	    .IF IDN <QIO>,<O>
	RESTORE	<R1>
	    .IFF ;IDN <O>
	MOV	LB.ITK(J),R0
	    .ENDC ;IDN <O>
104$:
	    .ENDC ;IDN <QIO>,<STORE>
.ENDM	HDRDMP
	    .IFF ;DF DMPHDR
;
DMPHIN=0
DMPHOU=0
DMPHLN=0
;
.MACRO	HDRDMP	QIO,QLINE,QN
.ENDM	HDRDMP
	    .ENDC ;DF DMPHDR
.PAGE
	.SBTTL	SYNCHRONOUS LINE DEBUGGING MACROS
;	CODE BY LAD 10/75
;
;
	    .IF DF SLSDMP
SLINDX=0	;MACRO CALL INDEX
.IIF LT SLSDMP-100,SLSDMP=100
;
.MACRO	DMPSLS	STORE
;
SLRCT:	.WORD	SLSDMP
SLRBF:	.BLKW	SLSDMP
SLRBE:	.WORD	SLRBF
;
SLXCT:	.WORD	SLSDMP
SLXBF:	.BLKW	SLSDMP
SLXBE:	.WORD	SLXBF
;
	SSSSQU	SLR
	SSSSQU	SLX
.ENDM	DMPSLS
;
.MACRO	SLX	QQA
	SLRX	SLX,QQA,\SLINDX
	SLINDX=SLINDX+1
.ENDM	SLX
;
.MACRO	SLR	QQA
	SLRX	SLR,QQA,\SLINDX
	SLINDX=SLINDX+1
.ENDM	SLR
;
.MACRO	SLRX	SQQ,QA,QB
	MOV	#SL..'QB,-(P)
	MOV	QA,-(P)
	JMP	SQQ'SPC
SL..'QB':
.ENDM	SLRX
;
.MACRO	SSSSQU	SQQ
SQQ'SPC:TST	SQQ'CT
	BEQ	SQQ'QB
	DEC	SQQ'CT
	CMP	SQQ'BE,#SQQ'BE
	BLO	.+10
	MOV	#SQQ'BF,SQQ'BE
	MOV	(P)+,@SQQ'BE
	ADD	#2,SQQ'BE
	RTS	PC
SQQ'QB:	TST	(P)+
	RTS	PC
.ENDM	SSSSQU
;
	    .IFF ;DF SLSDMP
.MACRO	DMPSLS	STORE
.ENDM	DMPSLS
;
.MACRO	SLR	QQA
.ENDM	SLR
;
.MACRO	SLX	QQA
.ENDM	SLX
;
	    .ENDC ;DF SLSDMP
.PAGE
	.SBTTL	MSGDMP DEBUGGING MACRO
;	CODE BY	LAD	10/75
;
;
	    .IF DF DMPMSG
DMPMSG=0
.MACRO	D$M	QTAG,QINDX,QOP
	    .IF B <QOP>
	QTAG'QINDX=.-2
	    .IFF
	.IF IDN <QOP>,<LOAD>
		MOV	QTAG'QINDX,R0
	.IFF
		.IF IDN <QOP>,<STORE>
			MOV	R0,QTAG'QINDX
		.IFF
			QOP	QTAG'QINDX
		.ENDC
	.ENDC
	    .ENDC ;B <QOP>
.ENDM	D$M
;
.MACRO	MSGDMP	QQN,QQW,QQB
	    .IF NE FT.SNK
.IIF NB <QQW>,	CMP	#'QQW,J
.IIF B <QQW>,	CMP	#0,J
	D$M	MD.B,\DMPMSG		;DEFINE	MD.B??=.-2
	BNE	79$
.IIF NB <QQN>,	TST	#'QQN
.IIF B <QQN>,	TST	#0
	D$M	MD.C,\DMPMSG		;DEFINE	MD.C??=.-2
	BEQ	79$
	SAVE	<R0>
	D$M	MD.S,\DMPMSG,TST	;	TST	MD.S??
	BNE	69$
	JSR	PC,ERSGET
	BEQ	78$
	CMP	(R0)+,(R0)+
	BR	68$
69$:
	MOV	#0,R0			;	MOV	MD.S??,R0
	D$M	MD.S,\DMPMSG		;DEFINE	MD.S??=.-2
	BEQ	78$
68$:
	    .IF IDN <QQB>,<R0>
	MOVB	(P),(R0)+
	    .IFF
	    .IF NB <QQB>
	MOVB	QQB,(R0)+
	    .IFF
	MOVB	R1,(R0)+
	    .ENDC ;NB <QQB>
	    .ENDC ;IDN <R0>
	D$M	MD.S,\DMPMSG,STORE	;	MOV	R0,MD.S??
	BIT	#CNKSIZ-1,R0
	BNE	78$
	SUB	#CNKSIZ,R0
	JSR	PC,SINKIT
	D$M	MD.S,\DMPMSG,CLR	;	CLR	MD.S??
	D$M	MD.C,\DMPMSG,DEC	;	DEC	MD.C??
78$:
	RESTORE	<R0>
79$:
	    .ENDC ;NE FT.SNK
	DMPMSG=DMPMSG+1
.ENDM	MSGDMP
	    .IFF
.MACRO	MSGDMP	QQN,QQW,QQB
.ENDM	MSGDMP
	    .ENDC ;DF DMPMSG
.PAGE
	.SBTTL	NCL TRACE MACRO
;	CODE BY LAD 2/76
;
.IIF NDF NCL.LG,NCL.LG=0
	    .IF NE NCL.LG
.MACRO	NCLLOG	LOGSIZ
.IF NB <LOGSIZ>
  .IF IDN <LOGSIZ>,<ALL>
	.IIF NE NCL.LG&1,	JSR	PC,NCLLOG	;LOG ALL ROUTED MSGS
  .IFF
    .IF IDN <LOGSIZ>,<DATA>
	.IIF NE NCL.LG&2,	JSR	PC,NCLLOG	;LOG DATA MSGS FOR US
    .IFF
BUGBF:
	.REPT	LOGSIZ*24
		.WORD	0
	.ENDR
BUGQ:	.WORD	BUGBF
    .ENDC ;IDN <LOGSIZ>,<DATA>
  .ENDC ;IDN <LOGSIZ>,ALL
.IFF ;NB <LOGSIZ>
	; SAVE 1ST WORDS OF MSG, AND TOP OF STACK
NCLLOG:
	MOV	R2,-(P)
	MOV	P,R2
	TST	(R2)+
	MOV	R3,-(P)
	MOV	BUGQ,R3
	CMP	R3,#BUGQ-23
	BLO	2$
	MOV	#BUGBF,R3
2$:	MOV	(R2)+,(R3)+
	MOV	(R2)+,(R3)+
	MOV	(R2)+,(R3)+
	MOV	R0,R2
	CMP	(R2)+,(R2)+
	MOV	(R2)+,(R3)+
	ADD	#CN.NCT-6,R2
	MOV	(R2)+,(R3)+
	MOV	(R2)+,(R3)+
	MOV	(R2)+,(R3)+
	MOV	(R2)+,(R3)+
	MOV	(R2)+,(R3)+
	MOV	(R2)+,(R3)+
	MOV	R3,BUGQ
	MOV	(P)+,R3
	MOV	(P)+,R2
	RTS	PC
.ENDC ;NB <LOGSIZ>
.ENDM	NCLLOG
	    .IFF ;NE NCL.LG
.MACRO	NCLLOG	LOGSIZ
.ENDM	NCLLOG
	    .ENDC ;NE NCL.LG
.PAGE
	.ENDR		;****** END OF DISABLED DEBUGGING SECTION ******
	.LIST
	.SBTTL MODULE END
	.SBTTL
;****************************************************************
;
;	END OF S - SYMBOL AND MACRO DEFINITION SECTION
;
;****************************************************************
.PAGE
	.TITLE	TERBOT - TERTIARY NETWORK BOOTSTRAP
	.IDENT	/X02.00/
 
;
; COPYRIGHT (C) 1978 BY
; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;
;
; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
; ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH  LICENSE AND WITH THE
; INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR  ANY  OTHER
; COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
; OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
; TRANSFERRED.
;
; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE  WITHOUT  NOTICE
; AND  SHOULD  NOT  BE  CONSTRUED  AS  A COMMITMENT BY DIGITAL EQUIPMENT
; CORPORATION.
;
; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR  RELIABILITY  OF  ITS
; SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
;
;
; MODULE DESCRIPTION:
;
;	TERTIARY BOOT PART I
;
;
;
; DISTRIBUTED SYSTEMS SOFTWARE ENGINEERING
;
; IDENT HISTORY:
;
; 1.00	10-FEB-78
;	VERSION 2.0 RELEASE
; 2.00	16-OCT-78
;	MODIFICATION FOR DN20/DN200 USE WITH CHECK11
;
  
;	THE BOOTSTRAP MESSAGES ARE OF THE FORM:
;
;	SYN,DLE,COUNT,F,S,FILL,FILL,ADDR,CRC1,DATA,CRC2
;
;	ALL ITEMS ARE 8-BIT QUANTITIES UNLESS OTHERWISE SPECIFIED
;
;	SYN-THE SYNC CHARACTER-OCTAL 226 OR 377 (ASYNCHRONOUS)
;	DLE-THE ASCII DLE CHARACTER-OCTAL 220
;	COUNT-THE 14-BIT COUNT FIELD-LENGTH OF DATA FIELD
;	F-THE FINAL BIT-LINK CONTROL
;	S-THE SELECT BIT-LINK CONTROL
;	FILL-A FILL CHARACTER-OCTAL 000
;	ADDR-THE ADDRESS OF STATION BEING BOOTED-FOR PT. TO PT. = 1
;	CRC1-THE 16-BIT CRC-16 COMPUTED ON DLE THROUGH ADDR
;	DATA-THE BOOT DATA AS FOLLOWS:
;		FOR BLOCKS WITHOUT CODE=XFER ADDRESS BLOCK:
;		COUNT .GT. 6
;		CODE,BLKNO.,BLOCK LOAD ADDR,CORE IMAGE DATA
;		FOR BLOCK WITH CODE=XFER ADDRESS BLOCK
;		COUNT .EQ. 6
;		CODE,BLKNO.,PROGRAM TRANSFER ADDRESS
;		ADDRESSES ARE 4 BYTES-32 BITS-LOW BIT FIRST
;		CODE - 2==>BOOT IMAGE DATA
;			0==>XFER ADDRESS
;		BLKNO. - BLOCK NO. STARTING AT 0
;	CRC2-THE 16-BIT CRC-16 COMPUTED ON THE DATA FIELD ONLY
;
;
;	***** NOTE *****
;
; IF A KT-11 MEMORY MANAGEMENT UNIT EXISTS ON THE TARGET COMPUTER,
; IT WILL BE ENABLED WHEN THE PROGRAM IS STARTED ON THE TARGET MACHINE
;
;
;	***** NOTE *****
;
; THIS VERSION OF THE TERTIARY LOADER RELOCATES THE LOADER TO HIGH CORE
; AND THEN INVOKES CHECK11, WHICH IS LOCATED IN LOW CORE BEYOND THE LOADER
; AND ITS DRIVER.  CHECK11 IS PASSED THE STARTING ADDRESS OF THE RELOCATED
; LOADER IN R0, AND RETURNS TO THE LOADER WHEN IT HAS FINISHED ITS
; DIAGNOSTICS.
;
;	***** NOTE *****
;
;
; THE LOADER AND DRIVER CODE IS POSITION-INDEPENDENT.  CHECK11 CODE IS NOT.
;
;-
;
; LOCAL SYMBOL DEFINITIONS
;
;
KISAR0=172340
KISDR0=172300
KISAR2=172344			;NOT DEFINED IN EXELIB
KISDR2=172304			;NOT DEFINED IN EXELIB
KISAR5=172352
KISDR5=172312
KISDR6=172314			;DITTO
KISAR6=172354			;DITTO AGAIN
KISAR7=172356
SR0=177572

BUFSIZ=262.			;BUFFER SIZE (MOP HEADER & LOAD DATA)
;
;	START OF BOOT PROGRAM
;
;
;	SET $DEVTP TO DEVICE TYPE AND $UNIT TO UNIT NUMBER
;	GET TYPE FROM DLLDRV AND UNIT NUMBER BY LOOKING
;	IN DEVICE SPACE
;
START:	MOV	PC,R2		;CURRENT PC
	ADD	#DEVNAM-.,R2	;DEVNAM TABLE ADDR
	ADD	#DEVTYP,R2	;INDEXED BY DEVICE TYPE
	MOV	(R2),$DEVTP	;STORE DEVICE TYPE IN ASCII
	MOV	CSRTAB-DEVNAM(R2),R4 ;GET CSR ADDRESS
	MOV	FLTTAB-DEVNAM(R2),R3 ;GET FLOAT TABLE VALUE
	BEQ	SETUNT		;IF EQ, NOT A FLOATING DEVICE
	MOV	#340,@#6	;SET NEW TRAP PS
	MOV	PC,R2		;CURRENT PC
	ADD	#NODEV-.,R2	;NODEV ADDR
	MOV	R2,@#4		;TRAP ROUTINE ADDR
	ADD	#DEVTAB-NODEV,R2 ;MODULO TABLE ADDR
FLOAT:	TST	(R4)		;LOOK FOR DEVICE
	MOVB	(R2),R5		;UP TO NEXT MODULO
	ADD	R5,R4		;
	INC	R4		;
	BIC	R5,R4		;
	TST	R3		;CHECK FOR END OF SEARCH
	BNE	FLOAT		;AGAIN
SETUNT:	SUB	R1,R4		;DISPLACEMENT FROM UNIT 0
	TST	#DEVTYP		;IS IT A DP-11
	BEQ	1$		;NO
	NEG	R4		;CHANGE DISPLACEMENT
1$:	ASR	R4		;DIVIDE BY 8.
	ASR	R4		;
	ASR	R4		;
	MOVB	R4,$UNIT	;SAVE UNIT NUMBER
	BR	SETREG		;TO RELOCATE ROUTINE
;
;
;	DEVICE NAME TABLE
;
DEVNAM:	.ASCII	'XP'
	.ASCII	'XU'
	.ASCII	'XL'
	.ASCII	'XQ'
	.ASCII	'XB'
	.ASCII	'XW'
	.ASCII	'XM'
	.ASCII	'X1'
	.ASCII	'XL'
;
;	FLOATING NUMBER TABLE
;
FLTTAB:	.WORD	0
	.WORD	3
	.WORD	0
	.WORD	2
	.WORD	0
	.WORD	4
	.WORD	0
	.WORD	0
	.WORD	0
;
;	CSR ADDRESS TABLE
;
CSRTAB:	.WORD	174770
	.WORD	160010
	.WORD	175610
	.WORD	160010
	.WORD	172414
	.WORD	160010
	.WORD	160740
	.WORD	176500
	.WORD	175610
;
;	FLOATING DEVICE MODULO TABLE
;
DEVTAB:	.BYTE	7	;DJ
	.BYTE	17	;DH
	.BYTE	7	;DQ
	.BYTE	7	;DU
	.BYTE	7	;DUP
	.BYTE	7	;LK11
	.BYTE	7	;DMC
	.BYTE	7	;DLV
	.BYTE	0	;FILLER
	
.EVEN
;
;	FLOAT DEVICE TRAP ROUTINE
;
NODEV:	CMPB	(R2)+,-(R3)
	RTI
	
;
; INPUTS:
;		R1 CONTAINS THE CSR ADDRESS OF THE LINK DEVICE
;
;
; OUTPUTS:	R1 CONTAINS CSR ADDRESS OF LINK DEVICE
;		R2 CONTAINS THE ASCII NAME OF THE LINK DEVICE TYPE
;-
;
SETREG:	MOV	PC,R0		;SET UP TO FIND TOP OF MEMORY
	ADD	#20$-.,R0	;
	MOV	R0,@#4		;SET TRAP ADDRESS
	MOV	#340,@#6	;PS
	CLR	SP		;RESET
10$:	CMP	(SP)+,(SP)	;FIND TOP
	BR	10$		;LOOP UNTIL TRAP
20$:
	CMP	(SP)+,(SP)+	;SET TO TOP OF CORE
	
;
; LOOK FOR MEMORY MANAGEMENT
;
	MOV	PC,R0		;SET UP MEMORY TRAP
	ADD	#70$-.,R0	;
	MOV	R0,@#4		;TRAP PC
	CLR	R0		;SET UP PAR'S TO 4K BOUNDARIES...
	MOV	#KISDR0,R4	;...AND ALL PDR'S FOR 4K R/W
	MOV	#8.,R3		;THERE ARE 8 APR'S
30$:	MOV	R0,KISAR0-KISDR0(R4) ;SET UP NEXT 4K LOW BOUNDARY
	MOV	#77406,(R4)+	;SET UP ASSOCIATED PDR
	ADD	#200,R0		;SET FOR NEXT 4K
	DEC	R3		;MORE?
	BNE	30$		;IF NE YES
;
; NOTE THAT SETTING PAR6 AND PAR7 HERE IS SUPERFLUOUS
;
;
; IF WE GET TO THIS CODE, WE USE THE MEMORY MANAGEMENT UNIT
;
;
	INCB	KT11		;YES, VIRGINIA, THERE REALLY IS A KT-11
	MOV	#7600,@#KISAR7	;POINT TO THE EXTERNAL PAGE
	INC	@#SR0		;ENABLE MEMORY MANAGEMENT
	MOV	#140,R0		;START LOOKING HERE
	MOV	#144000,SP	;THIS WILL BE 1ST NON-EXISTENT LOC
50$:	MOV	R0,@#KISAR6	;SET UP REGISTER
	CMP	R0,#7540	;AT ABSOLUTE END?
	BHIS	90$		;IF HIS YES
	TST	(SP)		;DOES THE MEMORY EXIST?
	ADD	#200,R0		;IF WE GET HERE, YES
	BR	50$		;TRY ANOTHER 4K
70$:	CMP	(SP)+,(SP)+	;NO MEMORY MANAGEMENT TODAY, THANKS
90$:	MOV	PC,R3		;COMPUTE ADDRESS OF MOVE START
	SUB	#.,R3		;  (INCLUDES
	ADD	#ENDDRV,R3	;  THE DRIVER)
	MOV	#ENDDRV,R2	;SET NUMBER
	SUB	#BT3STR,R2	;  OF WORDS
	ASR	R2		;  TO RELOCATE
100$:	MOV	-(R3),-(SP)	;MOVE A WORD
	DEC	R2		;MORE TO MOVE?
	BNE	100$		;IF NE YES
	CLR	-(SP)		;
	MOV	SP,(SP)		;CALCULATE
	SUB	#BUFSIZ+64.-2,(SP) ;  START OF BUFFER & UNUSED STACK
	MOV	(SP),-(SP)	;SPECIFY MEMORY LOAD LIMIT
;  ***NOTE***  SP NOW POINTS TO RELOCATED CODE MINUS 4
	CLR	R0		;START WITH LOAD 0
	MOV	#INIDRV+4,R5	;START
	SUB	#BT3STR,R5	;  UP
	ADD	SP,R5		;  THE
	JSR	PC,(R5)		;  DEVICE
	MOV	SP,R0		;SAVE BOOT ADDRESS
	ADD	#4,R0		;SKIP PAST THE CONTENTS OF THE STACK
	JMP	CHK.11		;INVOKE CHECK11 (WILL GO ON TO BOOT)
.PAGE
;
; COPYRIGHT (C) 1977,1978 DIGITAL EQUIPMENT CORPORATION, MAYNARD, MA 01754
;
;
;	MODULE:	CHECK11
;
;	DATE:	21-NOV-78
;
;	AUTHOR:	TOM PORCHER
;		TOM POWERS
;		LEE WEBBER
.TITLE CHK11 -  ONCE ONLY SYSTEM DIAGNOSTIC
.SBTTL CHK11 -  ONCE ONLY SYSTEM DIAGNOSTIC
;  22 SEP 1977 DMCC/EGF/JBS/LAD/EJW/TEP
;
;
;
; THIS CODE IS EXECUTED ONCE AND THEN OVERLAID
;
;
;
;
; THE CALL TO CHK11 IS AS FOLLOWS:
;	JSR	PC,CHK.11
;	.WORD	PTR	;POINTER TO ASCIZ NAME STRING AND EDIT POINTERS
;	RETURNS TO CALLER FOLLOWING POINTER WORD
;
;	CHK11 WILL DETERMINE WHAT HARDWARE IS PRESENT
;	  AND WILL PERFORM A FEW SIMPLE DIAGNOSTIC TESTS OF THE HDW
;
;	FOR DEV = < DH11, DM11BB, DP11, DQ11, DS11, DU11>
;	CHK11 WILL:	JSR PC,CKA'DEV
;			WITH (R3) = DEVICE VECTOR
;			AND (R4) = DEVICE ADR
;			AND (R1) = DEVICE ADR
;	ONCE FOR EACH DEVICE AND A FINAL:
;			JSR	PC,CKA'DEV WITH (R4)=0
;
; ALL SYMBOLS BEGINING CHK OR CK ARE RESERVED FOR CHK11
.PAGE
	.ENABL	AMA
; VERSION INFORMATION
;
CKNAME:	.ASCIZ	<15><12><12><14>"CHK11 Hardware Test"
	.EVEN
	.WORD	CKVMAJ,CKVMIN,CKVEDI
	.WORD	CKVWHN,CKVWHO
;
CKVMAJ	= 3	;MAJOR VERSION NUMBER
CKVMIN	= '	;MINOR VERSION LETTER (AS 'A)
CKVEDI	= 05.	;EDIT NUMBER
	ED.HIS	= 1		;TYPE OUT DETAILS
CKVWHN:	.ASCIZ	"5-Jun-82"	;LAST EDIT DATE
	.EVEN
CKVWHO:	.ASCIZ	"adp"		;LAST EDITOR
	.EVEN
;
;
;
;BE SURE ALL THE REGS ARE DEFINED PROPERLY
;
	R0=%0
	R1=%1
	R2=%2
	R3=%3
	R4=%4
	R5=%5
	R6=%6
	SP=%6
	R7=%7
	PC=%7
;
.IIF NDF FTKG11,FTKG11=	1	;0 IF KG11 MUST BE PRESENT
;
;OTHER DEFAULTS
	.IIF NDF FLOATV FLOATV=	300	;FIRST FLOATING VECTOR
	.IIF NDF FLOATD FLOATD=	160000	;FLOATING DEVICES BEGIN HERE
;
.IIF NDF DL10AD,DL10AD=.
	.BLKW	1		;PUT DL10 ADR HERE IF NOWHERE ELSE
;
.PAGE
.SBTTL	CHK11 MACROS
.SBTTL		CK11SC
;
;THIS MACRO IS USED FOR TYPING TEXT AND ERROR REPORTING.
;
;	ARG	BITS	;WHAT TO DO ON A TRAP
		CKEFAT=	B0	;FATAL ERROR - HALT
		CKEPC=	B1	;PRINT ADDRESS OF ERROR TRAP
		CKEMSG=	B2	;PRINT THE MESSAGE FOLLOWING CK11SC
		CKEDID=	B3	;PRINT DEVICE ID AND REG
		CKEMSE=	B4	;PRINT THE MESSAGE POINTED TO BY
				; THE ADDRESS FOLLOWING THE TRAP.
		CKENCL=	B5	;PRINT TEXT WITH OUT CR+LF
		CKEGB=	B6	;PRINT ADR/REG=XXXXX GD=XXXXX  BD=XXXXX XOR=XXXXX
;
;	ARG	MSG	;TEXT TO BE OUTPUT
;
;	ARG	COMENT	;ADD A COMMENT TO THE TRAP INSTRUCTION
;
;	ARG	STOPCD	;ON A FATAL ERROR VALUE TO BE PUT IN R0
;
.MACRO	CK11SC	BITS,MSG,COMENT,STOPCD
.IIF NB,STOPCD,	MOV	#STOPCD,CKSPCD	;VALUE TO DISPLAY ON FATAL ERROR
	    .IF B <MSG>
	TRAP	BITS		;COMENT
	    .IFF ;B <MSG.>
	    .IF	EQ,<BITS&CKEMSE>
	TRAP	BITS!CKEMSG		;COMENT
;;;;	ASCIZ	<MSG>			;MESSAGE TEXT FOLLOWS TRAP
	    .IFF
	TRAP	BITS&<^CCKEMSG>		;COMENT
	.WORD	MSG			;ADR OF MESSAGE FOLLOWS TRAP
	    .ENDC ;EQ <BITS..>
	    .ENDC ;B <MSG.>
.ENDM	CK11SC
;
;
;THIS MACRO IS USED FOR SAVING GOOD, BAD, AND ADR ON THE STACK
;PRIOR TO INVOKING CK11SC
;
;	ARG	GD		;GOOD DATA
;	ARG	BD		;BAD DATA
;	ARG	ADR		;ADDRESS WHERE IT HAPPENED
;
.MACRO	CKSERR	GD,BD,ADR
	MOV	GD,-(SP)			;SAVE GOOD (GD) ON STACK
	MOV	BD,-(SP)			;SAVE BAD (BD) ON STACK
	MOV	ADR,-(SP)		;SAVE ADDRESS (ADR) ON STACK
.ENDM	CKSERR
;
.MACRO	ABORT
	CK11SC	CKEFAT
.ENDM	ABORT
;
.PAGE
.SBTTL		$CKINT
;
;THIS MACRO IS USED TO CHECK INTERRUPT CONDITIONS
;
;	ARG	ENBADR		;DEVICE ADR TO ENABLE INTERRUPTS
;
;	ARG	INTADR		;DEVICE ADR TO GENERATE AN INTERRUPT
;
;	ARG	ENLBIT		;BIT TO ENABLE INTERRUPTS
;
;	ARG	INTBIT		;BITS TO CHECK INTERRUPT CONDITIONS
;
;	ARG	BITCLR		;BITS TO CLEAR INTERRUPT CONDITIONS
;				;IF CLEARING INTERRUPT BITS WON'T CLEAR
;				;THEM.  [EXAMPLE - DL10]
;
.MACRO	$CKINT	ENBADR,INTADR,ENLBIT,INTBIT,BITCLR
.IIF	NB,ENBADR,	MOV	ENBADR,R1			;LOAD ENABLE ADR
.IIF	NB,INTADR,	MOV	INTADR,R2			;LOAD INTERRUPT ADR
	JSR	R5,CKINT	;GO CHECK INTERRUPTS
	    .IIF NDF I.$$$$,I.XXXX = .
	    .IIF NDF I.$$$$,I.ENAB = . - I.XXXX
	.WORD	ENLBIT		;ENABLE BITS -  ENLBIT
	    .IIF NDF I.$$$$,I.INTS = . - I.XXXX
	.WORD	INTBIT		;INTERRUPT BITS -  INTBIT
	    .IIF NDF I.$$$$,I.INTC = . - I.XXXX
	.WORD	BITCLR+0	;BITS TO CLEAR DEVICE - ARG MAY BE BLANK
	    .IIF NDF I.$$$$,I.RTRN = . - I.XXXX
	    .IIF NDF I.$$$$,I.$$$$ = 0
.ENDM
;
.PAGE
.SBTTL		DEVICE
;
;THIS MACRO IS USED TO TO CALL THE ROUTINE TO CHECK A DEVICE
;AND ASSIGN THE FLOATING ADDRESS AND VECTORS IF THE DEVICE
;IS THE TYPE THAT REQUIRES IT.
;
;	ARG	A	;DEVICE ADDRESS OR 0 IF FLOATING DEVICE
;	ARG	MAXN	;MAXIMUM NUMBER OF DEVICES
;	ARG	VI	;VECTOR INCREMENT
;	ARG	HI	;HARDWARE INCREMENT
;	ARG	VM	;VECTOR MULTIPLE
;	ARG	NAM	;DEVICE NAME ABBREVIATION
;	ARG	FV	;FIRST VECTOR ADR (FIXED DEV ONLY)
;
.MACRO	DEVICE	A,MAXN,VI,HI,VM,NAM,FV
	    .IF DF X'NAM'11
	X'NAM'$$=X'NAM'11	;IF A LOCAL DIAGNOSTIC IS DEFINED, USE IT
	    .IFF
	X'NAM'$$=X.....		;ELSE USE NULL DIAGNOSTIC
	    .ENDC ;DF X'NAM'11
				;
				;
	    .IF DF CKA'NAM'11
	CKA'NAM'$$=CKA'NAM'11	;IF PROGRAM ENTRY DEFINED, USE IT
	    .IFF
	CKA'NAM'$$=CKPOPJ	;ELSE USE NULL SUBROUTINE
	    .ENDC ;DF CKA'NAM'11
				;
				;
	    .IF DF CKV'NAM'11
	CV'NAM'$$=CKV'NAM'11	;IF REAL VECTOR DEFINED, USE IT
	    .IFF
	CV'NAM'$$=0		;ELSE IGNORE EVERYTHING
	    .ENDC ;DF CKV'NAM'11
				;
				;
	.IIF NDF,NAM'.LVL,NAM'.LVL=0	;USE LEVEL NAME IF IT EXISTS
					;
	JSR	R5,CHKDEV		;CALL DEVICE ANALYZER
	    .IIF NDF D.$$$$,D.XXXX=.	;FIRST TIME THROUGH (ONLY)
					; THE OFFSETS ARE DEFINED
	    .IIF NDF D.$$$$,D.BADR=.-D.XXXX
	.WORD	A		;1ST NAM'11 ADR IS A
	    .IIF NDF D.$$$$,D.MAXL=.-D.XXXX
	.BYTE	<MAXN>		;MAXIMUM NUMBER OF NAM'11 IS MAXN,
	    .IIF NDF D.$$$$,D.VINC=.-D.XXXX
	.BYTE	<VI>		;VECTOR INCREMENT IS VI
	    .IIF NDF D.$$$$,D.HINC=.-D.XXXX
	.BYTE	<HI>		;HARDWARE INCREMENT IS HI,
	    .IIF NDF D.$$$$,D.VMUL=.-D.XXXX
	.BYTE	<VM>		;1ST VECTOR MULTIPLE IS VM
	    .IIF NDF D.$$$$,D.CNTP=.-D.XXXX
	.WORD	0		;WILL BECOME NUMBER OF DEVICES
	    .IIF NDF D.$$$$,D.NAMP=.-D.XXXX
	.WORD	N.'NAM'11		;ADDRESS OF ASCIZ NAME STRING
	    .IIF NDF D.$$$$,D.DIAG=.-D.XXXX
	.WORD	X'NAM'$$		;ADDRESS OF ROUTINE TO CHECK DEVICE
	    .IIF NDF D.$$$$,D.MAIN=.-D.XXXX
	.WORD	CKA'NAM'$$		;CALL FOR MAIN PROGRAM (CKA'NAM'11)
	    .IIF NDF D.$$$$,D.MPVC=.-D.XXXX
	.WORD	CV'NAM'$$		;POINTS TO VECTOR SETUP TABLE
	    .IIF NDF D.$$$$,D.CNTF=.-D.XXXX
	.WORD	0		;WILL CONTAIN NUMBER OF NAM'11 FOUND
	    .IIF NDF D.$$$$,D.FRSV=.-D.XXXX
	.WORD	0		;WILL CONTAIN FIRST NAM'11 VECTOR ADR
	    .IIF NDF D.$$$$,D.PRIO=.-D.XXXX
	.WORD	NAM'.LVL*40	;CONTAINS NAM'11 PI LEVEL
	    .IIF NDF D.$$$$,D.FVFD=.-D.XXXX
	.WORD	FV		;DEVICE FIRST VECTOR (FIXED DEV ONLY)
	    .IIF NDF D.$$$$,D.NEXT=.-D.XXXX
	    .IIF NDF D.$$$$,D.$$$$=0	;DEFINE DEFINITION STOPPER
.ENDM	DEVICE
;
;EDIT PAGE BREAK (FF)
.SBTTL		CHKCHR
;
;THIS MACRO IS USED FOR SETTING CHARACTERISTICS TABLE
;
;	ARG	DA		;DEVICE ADDRESS TO PUT IN CHARACTERISTICS TABLE
;
;	ARG	DV		;DEVICE VECTOR ADDRESS TO PUT IN TABLE
;
;	ARG	PI		;DEVICE PI LEVEL TO PUT IN TABLE
;
.MACRO	CHKCHR	DA,DV,PI
.IIF NB,<DA>,	MOV	DA,CHKCHR+CKDA	;PUT DA IN DEVICE ADR SLOT
.IIF NB,<DV>,	MOV	DV,CHKCHR+CKDV	;PUT DV IN DEVICE VEC SLOT
.IIF NB,<PI>,	MOV	PI,CHKCHR+CKPI	;PUT PI IN DEVICE INT LVL SLOT
.ENDM	CHKCHR
.PAGE
.SBTTL		CKVECT, CKVEC1
;
;"CKVECT" INVOKES "CKVEC1" TO BUILD A TABLE
;FOR EACH DEVICE.  THE INFORMATION IN THE TABLE IS OF THE FOLLOWING FORM:
;
;	CKV'NAM'11:
;		.BYTE	NUMBER OF MAIN ROUTINES
;		.BYTE	NUMBER OF VECTORS PER DEV
;		.WORD	NAM'VA'NUM
;
;	EXAMPLE:
;
;	1.	MAIN PROGRAM HAS 1 DQ11
;		THE MAIN PROGRAM MUST GIVE DQ #0 VECTOR A THE TAG:  DQVA0
;					   DQ #0 VECTOR B THE TAG:  DQVB0
;	THE RESULTING TABLE WILL BE:
;
;	CKVDQ11:.BYTE	1,2
;		DQAV0
;		DQBV0
;
;	2.	MAIN PROGRAM HAS 2 DQ11'S
;		THE MAIN PROGRAM MUST GIVE DQ #0 VECTOR A THE TAG:  DQVA0
;					   DQ #0 VECTOR B THE TAG:  DQVB0
;					   DQ #1 VECTOR A THE TAG:  DQVA1
;					   DQ #1 VECTOR B THE TAG:  DQVB1
;
;	THE RESULTING TABLE WILL BE:
;
;	CKVDQ11:.BYTE	2,2
;		DQVA0
;		DQVB0
;		DQVA1
;		DQVB1
;
;
;	ARG	NAM		;NAME (2 CHARACTERS)
;	ARG	NUMV		;NUMBER OF VECTORS PER DEVICE
;	ARG	MAXN		;MAXIMUM NUMBER OF DEVICES OF A TYPE
;
.MACRO	CKVECT	NAM,NUMV,MAXN
CKZQZQ=0
CV'NAM'11:.BYTE	NAM'QQQ,NUMV			;NUM OF VEC FOR EACH NAM'11 IS NUMV
NAM'QQQ=0				;DEFINE AND SET TO 0
	.REPT	MAXN
	CKVEC1	NAM,NUMV,\CKZQZQ
	CKZQZQ=CKZQZQ+1
	.ENDR
.ENDM	CKVECT
;
;
;
;
.MACRO	CKVEC1	NAM,NUMV,NUM
	    .IF DF,NAM'VA'NUM
	NAM'QQQ=NAM'QQQ+1		;COUNT NUMBER IN MAIN
.IIF GE,<NUMV-1>,	.WORD	NAM'VA'NUM		;VECTOR A FOR DEV NAM'11
.IIF GE,<NUMV-2>,	.WORD	NAM'VB'NUM		;VECTOR B FOR DEV NAM'11
.IIF GE,<NUMV-3>,	.WORD	NAM'VC'NUM		;VECTOR C FOR DEV NAM'11
.IIF GE,<NUMV-4>,	.WORD	NAM'VD'NUM		;VECTOR D FOR DEV NAM'11
	    .ENDC
.ENDM	CKVEC1
;
.MACRO	LDVECT	DEV
	    .IF DF DEV'INT
	MOV	#DEV'INT,DEV'VEC		;SET DEV TO GO TO DEV'VEC
	MOV	#DEV'LVL*40,DEV'VEC+2		; AND SET THE LEVEL.
	    .IFF
	MOV	0,@#0			;LEAVE ROOM FOR ENTRY TO BE PATCHED
	MOV	2,@#2			;
	    .ENDC
.ENDM	LDVECT
 
;
;  LIMIT FOR INTERRUPT VECTORS WHICH CHECK11 WILL MONITOR
;
 
$$HERE	= <CKNAME-START>&177700	;ABSOLUTE ADDRESS OF TOP OF CHK11
	.IF LT,<1000-$$HERE>
VCTLIM:	.WORD	$$HERE
	.IFF
VCTLIM:	.WORD	1000
	.ENDC
;
.PAGE
.SBTTL	CHK11 DEVICE NAME TABLE
;
.MACRO	NAMSTR	DEV,ABBR
N.'ABBR'11:
		.ASCIZ	"DEV"
.ENDM	NAMSTR
;
;NOTE: THIS LIST IS ALPHABETIZED BY DEVICE NAME, NOT DEVICE ABBREVIATION
;
	NAMSTR	<CD20>,CD
	NAMSTR	<CR11>,CR
	NAMSTR	<CTY IN>,CI
	NAMSTR	<CTY OUT>,CO
	NAMSTR	<DH11>,DH
	NAMSTR	<DJ11>,DJ
	NAMSTR	<DL10>,DL0
	NAMSTR	<DL11-A>,DL.A
	NAMSTR	<DL11-E>,DL.E
	NAMSTR	<DM11-BB>,DM
	NAMSTR	<DMC11>,DMC
	NAMSTR	<DN11>,DN
	NAMSTR	<DP11>,DP
	NAMSTR	<DQ11>,DQ
	NAMSTR	<DS11>,DS
	NAMSTR	<DTE20>,DTE2
	NAMSTR	<DU11>,DU
	NAMSTR	<DUP11>,DUP
	NAMSTR	<DV11>,DV
	NAMSTR	<DZ11>,DZ
	NAMSTR	<KG11-A>,KG
	NAMSTR	<KMC11>,KMC
	NAMSTR	<KT11>,KT
	NAMSTR	<KW11-L>,KW.L
	NAMSTR	<KW11-P>,KW.P
	NAMSTR	<LK11>,LK
	NAMSTR	<LP11>,LE
	NAMSTR	<LP20>,LP
	NAMSTR	<MF11-UP>,MM
	NAMSTR	<null device>,NL
	NAMSTR	<PA611-P>,P6
	NAMSTR	<PA611-R>,R6
	NAMSTR	<PP11>,PP
	NAMSTR	<PR11>,PR
	NAMSTR	<RC11>,RC
	NAMSTR	<RF11>,RF
	NAMSTR	<RK11>,RK
	NAMSTR	<RH11>,RH
	NAMSTR	<RP11-C>,RP
	NAMSTR	<RX11>,RX
	NAMSTR	<TA11>,TA
	NAMSTR	<TC11>,TC
	NAMSTR	<TM11>,TM
	.EVEN
.PAGE
CHKFLG:	.BLKW	1		;CHK11 FLAGS
	CKFERR=	B0		;ERROR DETECTED
	CKFIDT=	B15		;ID ALREADY TYPED
CKDEVN:	.BLKW	1		;UNIT # CURRENTLY BEING TESTED
CKDNAM:	.BLKW	1		;ADR OF DEVICE NAME(.ASCIZ)
;
CK.CAL:	.BLKW	1		;RETURN ADDRESS TO CALLER OF CHK11
CK.DMC:	.BLKW	1		;DMC CSR ADDRESS (FOR REMOTE REPORTING)
CK.CSP:	.BLKW	1		;CALLER'S SP ON ENTRY
CK.OSP:	.BLKW	1		;SAVE AREA FOR CK11'S SP
;
PHYLIM:	.BLKW	1		;LIMIT OF PHYSICAL MEMORY (BLOCKS)
NLINES	= 48.			;NUMBER OF DMC/KMC LINES, 4 PER DEVICE
MDCSRP:	.WORD	0		;POINTER INTO MDCSR TABLE
MDCSR:	.WORD	0,0,0,0,0,0,0,0	; (TWELVE ENTRIES FOR NOW)
		0,0,0,0		;
;
CKPOPJ:	RTS	PC		;CKPOPJ IS THE GENERAL NULL SUBROUTINE
CKHALT:	HALT			;CKHALT IS THE HARD ERROR ROUTINE
.IIF NDF CKADLX,CKADLX=CKPOPJ
.IIF NDF CKAMEM,CKAMEM=CKPOPJ
.IIF NDF CKAKW1,CKAKW1=CKPOPJ
.IIF NDF CKAKG1,CKAKG1=CKPOPJ
;EDIT PAGE BREAK (FF)
.SBTTL **** CHK.11 - CHK11 ENTRY, PROGRAM SETUP ****
;
CHK.11:	SPL	7		;PROCESSOR LEVEL TO 7
	MOV	R0,CK.CAL	;SAVE RETURN ADDRESS
	MOV	R1,CK.DMC	;SAVE THE CSR ADDRESS
	MOV	SP,CK.CSP	;SAVE CALLER'S SP
	MOV	#CHKSTK,SP	;SET UP CHK11'S SP
	MOV	R4,-(SP)	;SAVE THE LOADER'S
	MOV	R5,-(SP)	;  REGISTERS
	MOV	KISAR6,-(SP)	;SAVE PAGE 6 MAPPING
	MOV	KISDR6,-(SP)	;  REGISTERS (FOR CALLER'S STACK)
	MOV	#FLOATV,CHKFLV	;FLOATING INT VEC BEGIN HERE
	MOV	#FLOATD,CHKFLD	;FLOATING DEV ADR'S BEGIN HERE
	CLR	CHKFLG		;CLEAR CHK11 FLAGS
	CLR	CKSPCD		;CLEAR STOP CODE; NON 0 ON FATAL
				; ERROR PUTS C(CKSPCD) IN R0.
;
;INITIALIZE VECTOR SPACE
;
; THIS ROUTINE LOADS THE VECTOR AREA WITH ADDRESSES POINTING
;   INTO TABLE/CODE CHKINT - CHKINT IS USED TO FIELD MOST CHK11
;   INTERRUPTS AND CAN TELL WHICH VECTOR WAS USED BY DECODING
;   THE CONDITION CODE BITS AND THE ENTRY IN CHKINT WHICH WAS USED -
;   THE REFERENCES TO "LIMIT" AND "ADD #CHKISZ,R1" IN THE CODE BELOW
;   ARE WHAT DETERMINE THE CHKINT ENTRY LOCATION
;
CKINTS:	MOV	@#14,R3		;SAVE ODT ADDRESS
	CLR	R0		;START LOADING AT ADR 0
	MOV	#CHKINT,R1	;WHERE TO GO ON INTERRUPT
	MOV	#BR7,R2		;INTERRUPT PS
				;
33$:	MOV	R1,(R0)+	;SET INTERRUPT VECTOR
	MOV	R2,(R0)+	;SET INTERRUPT LEVEL
	INC	R2		;UP VECTOR COUNTER
	BIT	#77,R0		;HAVE WE HIT A LIMIT ?
	BNE	35$		;NO
	ADD	#CHKISZ,R1	;YES, CHANGE VECT TO NEXT CHKINT BLOCK
	MOV	#BR7,R2		;RESET PS
35$:	CMP	R0,VCTLIM	;FILL VECTORS UP TO VECTOR LIMIT
	BLO	33$		;MORE TO DO
				;
	MOV	#CHKERR,TRPVEC	;WHERE TO GO ON TRAP INSTRUCTION
	MOV	R3,@#14		;RESTORE ODT ADDRESS
	FALLR	CHKCTY		;
.PAGE
;NOW CHECK THE CTY (CONSOLE TTY)
;
CHKCTY:	MOV	#10$,NXMVEC	;WHERE TO TRAP IF NO CTY
	BIC	#CKFIDT,CHKFLG	;SO WE PRINT DEV ID
	MOV	#100000,CKTRPT	;ASSUME A CTY EXISTS AS THE REPORT DEV
	TST	CTOSTS		;IF ANY OF THESE FOUR TST'S TRAPS
	TST	CTOCHR		;  THEN WE DEEM THERE IS NO CTY
	TST	CTISTS		;
	TST	CTICHR		;
	MOV	#CKBUST,NXMVEC	;CTY EXISTS, RESET BUS ERROR VECTOR
	BR	14$		;
				;
	10$:	CMP	(SP)+,(SP)+	;POP TRAP
		MOV	#200,CKTRPT ;NO CTY EXISTS, ASSUME REMOTE REPORTING
		MOV	#CKBUST,NXMVEC ;RESET BUS ERROR VECTOR
		JMP	CHKCKD	;SKIP TO END OF CTY CHECK
				;
14$:				; CHECK TO SEE IF CTY OUTPUT SHOULD BE
				;    SUPPRESSED OR DIVERTED OR BOTH
	MOV	#100200,R2	;PLAN TO DIRECT OUTPUT TO CTY
	.REPT	0	;***OMITTED***;
30$:	JSR	R0,CKTCRL	;ASK FOR DIRECTION
	.ASCIZ	"IS THIS CTY THE DEFAULT REPORTING DEVICE? (Y OR N) "<377>
	.EVEN			;
	JSR	PC,CKGYES	;WAIT FOR ANSWER
	BCS	30$		;
	BEQ	40$		;"YES"
	CLR	R2		;"NO", DON'T OUTPUT TO CTY
40$:	JSR	R0,CKTCRL	;CHECK FOR REMOTE REPORTING
	.ASCIZ	"IS OUTPUT TO BE DIRECTED TO A REMOTE RECORDER? (Y OR N) "<377>
	.EVEN			;
	JSR	PC,CKGYES	;WAIT FOR ANSWER
	BCS	40$		;
	BNE	50$		;"NO", DON'T OUTPUT REMOTELY
	.ENDR		;***OMITTED PART***;
50$:	MOV	R2,CKTRPT	;SAVE REQUESTED MODE
				;TEST CTY
	MOV	#CTOSTS,R4	;CTY OUTPUT STATUS
	MOV	R4,CHKCHR+CKDA	;DEV ADR
	MOV	R4,R1		;CHKBIT NEEDS ADR IN R1
	MOV	#CTOVEC,CHKCHR+CKDV;CTY OUTPUT VECTOR
	MOV	#N.CO11,CKDNAM	;NAME ADDRESS
	CLR	CKDEVN		;DEVICE 0
	JSR	R5,CHKBIT	;CHECK THE FOLLOWING BITS FOR R/W
	.WORD	CO.INE!CO..MM	;BITS TO CHECK FOR R/W
	MOV	#CO.INE,(R4)	;ENABLE INTERRUPTS
	JSR	R5,CHKINL	;CHECK INTERRUPT AND FIND DEV LEVEL
	.WORD	ALLBTS		;TIME LOOP CONSTANT
	CLR	(R4)		;CLR DEV OUT
				;
	FALLR	CHKCKB		;
.PAGE
;NOW CHECK THE KBRD SECTION
;
CHKCKB:	BIC	#CKFIDT,CHKFLG	;PRINT DEV ID
	MOV	#CTISTS,R4	;KBRD STATUS REG
	MOV	R4,CHKCHR+CKDA	;DEV ADR
	MOV	R4,R1		;CHKBIT NEEDS ADR IN R1
	MOV	#CTIVEC,CHKCHR+CKDV ;VECTOR ADR
	MOV	#N.CI11,CKDNAM	;ADR OF DEV NAME
	JSR	R5,CHKBIT	;CHECK THE FOLLOWING BITS
	.WORD	CI.INE		;BITS TO CHECK R/W
				;
15$:	MOV	#CKNAME,R0	;GET ADDR OF .ASCIZ \PROG NAME\
	JSR	PC,CKTTXT	;TYPE PROGRAM NAME, ETC.
	MOV	R0,R2		;GET ADDR OF EDIT DATA (FOLLOWS PROG NAME)
	JSR	R0,CKTCRL	;
	.ASCIZ	"version "	;
	.EVEN			;
	MOV	(R2)+,R0	;GET MAJOR VERSION NUMBER
	JSR	PC,CKTOCT	;TYPE IT
	MOV	(R2)+,R1	;GET MINOR VERSION LETTER
	BEQ	20$		;NOT THERE
	JSR	PC,CKTCHR	;TYPE IT
20$:	MOVB	#'(,R1		;TYPE EDIT NUMBER IN ()
	JSR	PC,CKTCHR	;
	MOV	(R2)+,R0	;GET EDIT NUMBER
	JSR	PC,CKTOCT	;TYPE IT
	MOVB	#'),R1		;
	JSR	PC,CKTCHR	;
	    .IF DF ED.HIS	;DO NEXT ONLY IF LAST EDIT HISTORY REQ'D
	JSR	R0,CKTSTR	;
	.ASCIZ	" of "		;
	.EVEN			;
	MOV	(R2)+,R0	;DATE STRING ADDRESS
	JSR	PC,CKTTXT	;
	JSR	R0,CKTSTR	;
	.ASCIZ	" by "		;
	.EVEN			;
	MOV	(R2)+,R0	;
	JSR	PC,CKTTXT	;
	    .ENDC ;DF ED.HIS	;
	JSR	R0,CKTCRL	;
	.ASCIZ	"Testing begins..."<15><12>
	.EVEN			;
				;
CHKCKD:	FALLR	CKCPU		;
;EDIT PAGE BREAK (FF)
; DETERMINE PROCESSOR MODEL NUMBER
;
CKCPU:	JSR	R0,CKTCRL	;
	.ASCIZ	"THE PROCESSOR SEEMS TO BE A "
	.EVEN			;
				;
	MOV	#CKWRD,R0	;GET ADDRESS OF TEST WORD
;;;;	MOV	R0,(R0)+	;STORE AND AUTOINC ON SAME REGISTER
	.WORD	10020		;	(PRE-ASSEMBLE TO PREVENT Z ERROR)
	MOV	#5$,R0		;GET BUMPER TABLE ADDRESS
	CMP	CKWRD,#CKWRD	;BUMP BEFORE STORE?
	BEQ	3$		;NO, CPU IS NEWER THAN THAT
				;YES, CPU IS OF /20 /40 VINTAGE
	ADD	#9$-5$,R0	;MODIFY ADDRESS INTO BUMPER TABLE
				;
3$: ;;;	JMP	(R0)+		;BUMP BEFORE JUMP?
	.WORD	120		;	(PRE-ASSEMBLE TO PREVENT Z ERROR)
5$:	BR	10$		;NO, CPU IS LIKE /04 /34 /45
	BR	CK05		;YES, CPU IS /05 /10
				;BUMP BEFORE JUMP?
9$:	BR	CK40		;NO, CPU IS /40
	BR	CK20		;YES, CPU IS /15 OR /20
				;
10$:				;CPU IS /04 /34/ OR /40 OR HIGHER
	MOV	@#4,-(SP)	;SAVE BUS ERROR VECTOR
	MOV	#20$,@#4	;SET LOCAL ONE
	MOV	#177770,R0	;TRY TO FIND NONEXISTENT MEMORY
15$:	TST	(R0)		;IS THIS MEMORY HERE?
	SUB	#2,R0		;YES, THERE WAS NO TRAP
	BNE	15$		;LOOK AGAIN (UNLESS ALL MEMORY SEEN)
				;THIS IS RIDICULOUS! THERE ARE NO HOLES
				;  IN MEMORY, OR THE BUS ERROR TRAPPER
				;  DOESN'T WORK
17$:	CK11SC	CKEPC,<NO NXM??>,<NO NONEXISTENT MEMORY TRAP>
	.ASCIZ	"NO NXM??"	;
	.EVEN			;
	BR	26$		;
				;
20$:	MOV	#25$,@#4	;SET UP NEXT BUS ERROR ADDRESS
	MOV	R0,R1		;COPY ADDRESS WHICH DIDN'T ANSWER
	MOV	R2,(R0)+	;REPEAT TRAP
	BR	17$		;YOU CAN'T GET HERE UNLESS TRAP FAILS
25$:	ADD	#10,SP		;POP BOTH TRAPS
26$:	MOV	(SP)+,@#4	;RESTORE SAVED BUS ERROR VECTOR
	CMP	R0,R1		;DID R0 POP DURING TRAP?
	BEQ	CK04		;NO, CPU IS /04
	MOV	@#10,-(SP)	;YES, SAVE RESERVED INSTRUCTION VECTOR
	MOV	#30$,@#10	;SET UP A NEW ONE
	CLR	R0		;R0 WILL STAY CLEAR IF CPU IS /45
	.WORD	106700		;11/34 MFPS INSTR (OP NAME=A MACRO NAME)
	INC	R0		;DIDN'T TRAP, CPU IS /34 (OR /03)
30$:	MOV	(SP)+,@#10	;RESTORE RES INSTR VECTOR
	TST	R0		;WAS THERE A TRAP?
	BNE	CK34		;NO, CPU IS 11/34
	BR	CK45		;YES, CPU IS 11/45
				;
CKWRD:	.WORD	0		;CPU ID TEST WORD
CKCPUN:	.WORD	0		;CPU MODEL NUMBER (DECIMAL)
	    .ENABL LSB		;
4$:	.BYTE	4.
	.ASCIZ	"KD11-D (11/04)"
5$:	.BYTE	5.
	.ASCIZ	"KD11-B (11/05 OR 11/10)"
20$:	.BYTE	20.
	.ASCIZ	"KA11 (11/20) OR KC11 (11/15)"
34$:	.BYTE	34.
	.ASCIZ	"KD11-E (11/34)"
40$:	.BYTE	40.
	.ASCIZ	"KD11-A (11/35 OR 11/40)"
45$:	.BYTE	45.
	.ASCIZ	"KB11-A (11/45)"
	.EVEN			;
				;
CK04:	MOV	#4$,R0		;
	BR	CKCPUE		;
				;
CK05:	MOV	#5$,R0		;
	BR	CKCPUE		;
				;
CK20:	MOV	#20$,R0		;
	BR	CKCPUE		;
				;
CK34:	MOV	#34$,R0		;
	BR	CKCPUE		;
				;
CK40:	MOV	#40$,R0		;
	BR	CKCPUE		;
				;
CK45:	MOV	#45$,R0		;
	BR	CKCPUE		;
	    .DSABL LSB		;
				;
CKCPUE:	MOVB	(R0)+,CKCPUN	;SAVE PROCESSOR MODEL NUMBER AWAY FOR REFERENCE
	JSR	PC,CKTTXT	;TYPE OUT THE ID TEXT
	    .IF NE 1
	JSR	R0,CKTCRL	;TYPE OUT EXPECTED MODEL NUMBER
	.ASCIZ	"	CHK11 EXPECTED AN 11/"
	.EVEN			;
	MOV	#PDP11,R0	;ADD NUMBER
	JSR	PC,CKTDEC
	    .ENDC ;NE 1
				;
	FALLR	CKDLXB		;FALL INTO DL10 SEEKER
.PAGE
;DETERMINE THE DL10 BASE ADDRESS
;
;
.IIF NDF FTDL10,FTDL10=0
;
CKDLXB:
	    .IF NE FTDL10
	MOV	#CHKFFB,R0		;SET ADDRESS TO START LOOKING FOR A DL10
	CLR	DL10AD			;SET FOR NO DL10
	MOV	#10$,NXMVEC		;WHERE TO GO ON A NXM
3$:	MOV	#DL.CNX!DL.CPE!DL.CWC!DL.11C,R1	;BITS TO SET IN DL10
	MOV	(R0),R2			;SAVE CONTENTS AS IT MAY BE CORE
	BIS	R1,(R0)			;CLEAR THESE CONDITIONS IF DL10
					; OR IF MEMORY BITS WILL BE SET
	ASL	R1			;POSITION BITS FOR SETTING CONDITIONS
	CLR	(R0)			;SEE IF SOMETHING THERE AND CLEAR IF IT IS THERE
	TST	(R0)			;MAKE SURE ITS CLEAR SINCE ITS THERE
	BEQ	1$			;BRANCH IF IT CLEARED
	CLR	-(SP)			;RESULT SHOULD BE 0
	MOV	(R0),-(SP)		;SAVE WHAT IT WAS
	MOV	R0,-(SP)			;SAVE THE ADDRESS WHERE IT HAPPENED
	CK11SC	<CKEPC!CKEGB>,<Can't Clear DL10 or MEM>,<CLR @R0 DIDN'T CLEAR @R0>,<S..DL10>
	.ASCIZ	\Can't Clear DL10 or MEM\<377>
	.EVEN
	BR	1$			;
1$:	BIS	R1,(R0)			;NOW SET DL10 BITS
	CMP	R1,(R0)			;SEE IF THEY SET BE IT MEMORY OR DL10
	BEQ	2$			;BRANCH IF THE SET OK
	CKSERR	R1,<(R0)>,R0		;SAVE GD,BD,ADR
	CK11SC	<CKEPC!CKEGB>,<DL10 or Mem Err>,<EITHER DL10 IS BAD OR MEMORY IS BAD>,<S..DL10>
	.ASCIZ	\DL10 or Mem Err\<377>
	.EVEN
	BR	2$			;
2$:	CLC				;CARRY MUST BE CLR
	ROR	R1			;SHIFT TO CLEAR BITS JUST SET
	BIS	R1,(R0)			;SET BITS, IF DL10 ALL BITS SHOULD BE 0
	TST	(R0)			;SEE IF ALL 0
	BEQ	4$			;BRANCH IF SO
6$:	MOV	R2,(R0)			;RESTORE MEMORY
7$:	ADD	#4000,R0		;GO TO NEXT POSSIBLE DL10 ADR
	CMP	R0,#160000		;TIME TO STOP CHECKING FOR DL10?
	BLO	3$			;BRANCH IF NOT
	BR	5$			;NEVER FOUND A DL10
					;
10$:	ADD	#4,P			;FLUSH NXM TRAP
	BR	7$			;GO CHECK NEXT POSSIBLE ADR
					;
4$:					;DL10 FOUND
	MOV	R0,DL10AD		;PUT DL10 BASE ADDR WE FOUND AWAY
	JSR	PC,CKADLX		;PRINT DL10 BASE ADDR
	    .ENDC ;NE FTDL10
5$:	FALLR	CHKMAP			;
.PAGE
; CHECK TO SEE IF SYSTEM IS MAPPED
;
CHKMAP:
	    .IIF NDF MMGSR0,MMGSR0 = 177572
				;
	MOV	#48$,NXMVEC	;SET UP BUS ERROR VECTOR
	MOV	MMGSR0,R0	;READ MEM MGT STATUS
				;
	    .IF NDF M$$MGE
	CK11SC	<CKEMSG>,<WRONG VERSION>
	.ASCIZ	"A NON-MAPPING CHK11 IS LOADED ON A MAPPED SYSTEM"<15><12><377>
	.EVEN			;
	BR	63$		;
				;
48$:	CMP	(SP)+,(SP)+	;POP TRAP, IGNORE IT (IT WAS HOPED FOR)
	FALLR	63$		;DROP RIGHT OUT
	    .IFF
	BR	63$		;NO TRAP, THAT'S WHAT WAS EXPECTED
				;TRAP, REPORT
48$:	CK11SC	<CKEMSG>,<WRONG VERSION>
	.ASCIZ	"A MAPPING CHK11 IS LOADED ON UNMAPPED HARDWARE"<15><12><377>
	ABORT			;
	.EVEN			;
	    .ENDC ;NDF M$$MGE
63$:	FALLR	CHKMMG		;CHECK MEMORY MGT
;EDIT PAGE BREAK (FF)
.SBTTL		CHECK KT11 HARDWARE
;
;VERIFY MEMORY MANAGEMENT HARDWARE - *** CODED FOR 11/34 SUBSET ***
;
CHKMMG:				;
	    .IF DF M$$MGE
	JSR	R0,CKTCRL	;
	.ASCIZ	<12>"KT11 memory management test"
	.EVEN			;
	MOV	#MMGVEC,R4	;SAVE ADDRESS OF MEM MGT VECTOR
	MOV	(R4),-(SP)	;SAVE CURRENT MEM MGT VECTOR
	MOV	#25$,(R4)	;SET MEM MGT VECTOR TO "BAD TRAP"
	MOV	#PD.PLF!<6*PD.AC0>,R0 ;SET UP CONSTANT FOR FULL PAGE, R/W ACCESS
	BIT	#MG.ENB,MMGSR0	;MEM MGT ALREADY ENABLED?
	BNE	10$		;YES, DON'T MESS
	CLR	KISAR0		;NO, SET UP REASONABLY, AS APR0 TO PAGE ZERO
	MOV	R0,KISDR0	;FULL PAGE ACCESS, R/W, EXPAND UP
	MOV	#PAGE1B,KISAR1	;MAP THIS PROGRAM TO SELF
	MOV	R0,KISDR1	;INCLUDE SAME TOTAL ACCESS
	MOV	#PAGE7B,KISAR7	;SPECIAL MAP TO I/O PAGE
	MOV	R0,KISDR7	;
	INC	MMGSR0		;TURN ON MEMORY MANAGEMENT
				;
10$:				;RELOCATION CONSISTENCY CHECK
				;
	MOV	KISAR0,KISAR5	;MAP APR5 TO SAME MEMORY AS APR0
	MOV	KISDR0,KISDR5	;  AND COPY OVER THE PDR TOO
	MOV	#PAGE0+302,R1	;GET POINTERS INTO PAGES 0 AND 5
	MOV	#PAGE5+302,R2	;  THE OFFSET INTO THE PAGE IS MOSTLY ARBITRARY
				;
	MOV	(R1),-(SP)	;SAVE THE CURRENT CONTENTS OF THE DIDDLE LOC
16$:	MOV	PC,(R2)		;ENSURE TEST LOCATION HAS NON-ZERO CONTENTS
	CLR	(R1)		;CLEAR THE TEST LOCATION THROUGH THE OTHER PTR
	TST	(R2)		;DID IT REALLY CLEAR?
	BNE	20$		;NO, WHAT A SHAME
	MOV	PC,(R1)		;YES, ENSURE IT'S NOT ZERO AGAIN
	CMP	(R1),(R2)	;STILL MATCH?
	BNE	20$		;NO, THAT'S FUNNY, IT WORKED BEFORE
				;
	CMP	KISAR0,KISAR5	;DONE OFFSET TEST YET?
	BNE	30$		;YES
	ADD	#2,KISAR5	;NO, CHANGE APR6 UP
	SUB	#2*BSFACT,R2	;  AND PAGE POINTER DOWN ACCORDINGLY
	BR	16$		;REPEAT TEST FOR DIFFERENT RELOCATION ADDRESSES
				;
20$:	CK11SC	CKEMSE,101$	;
	BR	30$		;
25$:	CK11SC	CKEMSE,104$	;
	BR	26$		;
26$:	RTI			;
				;
30$:	MOV	(SP)+,(R1)	;RESTORE ORIGINAL TEST WORD CONTENTS
				;
				;PAGE LENGTH PROTECTION TEST
				;
	MOV	KISAR0,KISAR5	;USE VECTOR SPACE AGAIN FOR TEST
	MOV	#PD.PL0!<6*PD.AC0>,KISDR5 ;SET 2 BLOCK PAGE, R/W, UP
	MOV	#PAGE0+<2*BSFACT>-2,R1 ;SET PTRS NEAR PAGE BOUNDARY
	MOV	#PAGE5+<2*BSFACT>-2,R2 ;
	MOV	(R1)+,-(SP)	;FETCH FROM BELOW BOUNDARY
	MOV	(SP)+,(R2)+	;WRITE IT BACK, DIFFERENT PTR, SHOULDN'T TRAP
	MOV	(R1)+,-(SP)	;FETCH FROM ABOVE BOUNDARY, PAGE 0, NO TRAP
	MOV	#45$,(R4)	;SET UP TO EXPECT TRAP
	MOV	(SP)+,(R2)+	;WRITE BACK TO TEST LOCATION, EXPECT TRAP
				;NO TRAP, THAT'S BAD
40$:	CK11SC	CKEMSE,107$	;
	CMP	-(SP),-(SP)	;FAKE TRAP
				;
45$:	CMP	(SP)+,(SP)+	;GOOD TRAP, POP IT
	MOV	#25$,(R4)	;RESET TO BAD TRAP MSG
	BIT	#MG.ANR!MG.ARO,MMGSR0 ;TRAP FOR RIGHT REASON?
	BEQ	47$		;YES, KEEP ON KEEPIN' ON
	CK11SC	CKEMSE,107$	;NO, GOOD GRIEF!
	BR	47$		;
47$:				;
				;**** CONSIDER ADDING HERE THE SAME TYPE OF
				;     TEST FOR A DOWNWARD EXPANDABLE PAGE ****
				;
				;ACCESS CONTROL MODE TEST
				;
	MOV	KISAR0,KISAR5	;USE THE VECTOR AREA AGAIN
	MOV	#PD.PLF+<6*PD.AC0>,KISDR5 ;RESET TO FULL PAGE, FULL ACCESS
	MOV	#PAGE5+52,R2	;RESET POINTER TO ARBITRARY LOCATION IN PAGE
	MOV	#50$,(R4)	;SET UP THE EXPECTED BAD TRAP HANDLER
	MOV	(R2),-(SP)	;READ (DON'T TRAP)
	MOV	(SP)+,(R2)	;PUT IT BACK (DON'T TRAP)
	MOVB	#PD.AC0*2,KISDR5 ;SET PDR FOR READ ONLY ACCESS
	MOV	(R2),-(SP)	;READ AGAIN (DON'T TRAP)
	MOV	#60$,(R4)	;RESET TRAP VECTOR AGAIN
	MOV	(SP)+,(R2)	;WRITE IT BACK AGAIN, AND FINALLY TRAP!
	CMP	-(SP),-(SP)	;DIDN'T TRAP, HAVE TO FAKE IT
				;
	50$:	CK11SC	CKEMSE,110$	;BAD TRAP, OR NON-TRAP, DEPENDING
		BR	62$		;
					;
	55$:	ADD	#2,(SP)		;GOOD TRAP, SKIP ERROR BRANCH
		RTI			;  ON RETURN
				;
60$:	CMP	(SP)+,(SP)+	;GOOD TRAP, POP IT
62$:	MOV	#67$,(R4)	;CHANGE TRAP VECTOR STILL AGAIN
	MOV	#PD.PLF+<PD.AC0*4>,KISDR5 ;SET PDR FOR ILLEGAL ACCESS
65$:	MOV	(R2),R1		;TRY TO READ, EXPECT A TRAP
	CK11SC	<CKEMSE!CKEPC>,110$ ;DIDN'T, ERROR
	MOV	R1,(R2)		;TRY A WRITE, EXPECT A TRAP
	CK11SC	<CKEMSE!CKEPC>,110$ ;DIDN'T, ERROR
	BIT	#PD.ACF,KISDR5	;DONE ALL ACF MODES YET?
	BEQ	70$		;YES, GO ON
	BIC	#PD.ACF,KISDR5	;NO, CLEAR ACF FOR LAST ILLEGAL MODE
	BR	65$		;REPEAT TEST
				;
	67$:	ADD	#4,(SP)	;GOOD TRAP, POP IT
		RTI		;
				;
101$:	.ASCIZ	"	inconsistent relocation"<377>
104$:	.ASCIZ	"	unexpected mem mgt trap"<377>
107$:	.ASCIZ	"	mem mgt page length protection failure"<377>
110$:	.ASCIZ	"	mem mgt access mode control failure"<377>
	.EVEN			;
				;
70$:	MOV	(SP)+,(R4)	;RESTORE PREVIOUS MEMORY MANAGEMENT TRAP VECTOR
	    .IFF
	JSR	R0,CKTCRL	;
	.ASCIZ	"NO MEM MGT TEST"
	.EVEN			;
	    .ENDC ;DF M$$MGE
	FALLR	CHKCOR		;
.PAGE
; SEE HOW MUCH CORE IS PRESENT
;
CHKCOR:				;
	    .IF NDF M$$MGE
				;UNMAPPED SNIFFER
	CLR	R0		;START SMALL
	MOV	#20$,NXMVEC	;SET BUS TRAP VECTOR
10$:	TST	(R0)+		;CHECK NEXT LOCATION
	CMP	R0,DL10AD	;SEE IF NEXT WORD IS DL10
	BNE	10$		;
	BR	21$		;
				;
20$:	CMP	(SP)+,(SP)+	;FLUSH STACK
	SUB	#2,R0		;MAKE 2 LESS SO WE HAVE 1ST NXM LOC
21$:	MOV	R0,PHYLIM	;SAVE ADR OF 1ST NXM LOCATION
	JSR	PC,CKAMEM	;PRINT LAST MEM LOCATION
	    .IFF
				;MAPPED SNIFFER
	JSR	R0,CKTCRL	;ADVERTISE RANGES OF MEMORY
	.ASCIZ	<12>"PHYSICAL MEMORY HAS ABSOLUTE LIMITS OF "
	.EVEN			;
	CLR	KISAR5		;START AT ZERO MEMORY
	MOV	#PD.PLF!<6*PD.AC0>,KISDR5 ;FULL PAGE, R/W ACCESS
	CLR	R0		;START OF CURRENT BLOCK ADDRESS
	CLR	R1		;ACCUMULATED PAGE COUNT
	CLR	R3		;CURRENT BLOCK PAGE COUNT
	MOV	#35$,NXMVEC	;SET UP BUS ERROR VECTOR
				;
30$:	MOV	#BSFACT,R2	;SET BYTE COUNT OF PAGE
31$:	TSTB	PAGE5-1(R2)	;READ A BYTE FROM THE ADDRESSED PAGE
	BR	43$		;NO TRAP
				;
	35$:	CMP	(SP)+,(SP)+	;TRAP, POP IT
		TST	R3		;ANY PAGES FOUND?
		BEQ	39$		;NO, SKIP REPORT
		JSR	PC,65$		;YES, REPORT RANGE
	39$:	INC	KISAR5		;COMPUTE NEXT BIAS VALUE
		MOV	KISAR5,R0	;SAVE IT AS START ADDRESS OF NEXT RANGE
		BR	52$		;RETURN TO TEST LOOP
				;
43$:	SOB	R2,31$		;LOOP OVER ALL BYTES ON CURRENT PAGE
	INC	R3		;NO TRAP, UP BLOCK COUNT
	INC	KISAR5		;UP PAGE BIAS
				;
52$:	CMP	KISAR5,#PAGE7B	;DONE ALL POSSIBLE MEMORY SPACE?
	BLO	30$		;NOT YET
				;YES
	TST	R3		;ANY BLOCKS FOUND AT END OF MEMORY?
	BEQ	54$		;NO
	JSR	PC,65$		;YES, REPORT LAST BLOCK
54$:	MOV	R1,PHYLIM	;SAVE NUMBER OF BLOCKS OF MEMORY
	JSR	R0,CKTCRL	;SUMMARIZE MEMORY SIZE DATA
	.ASCIZ	"	FOR A TOTAL OF "
	.EVEN			;
	MOV	R1,R0		;
	ASR	R0		;DIVIDE NUMBER OF 32 WORD BLOCKS
	ASR	R0		;  BY 32 TO GET NUMBER OF KW
	ASR	R0		;
	ASR	R0		;
	ASR	R0		;
	JSR	PC,CKTDEC	;OUTPUT MEMORY SIZE IN KW DECIMAL
	BIT	#37,R1		;REMAINDER OVER EXACT KW AMOUNT?
	BEQ	62$		;NO
	CK11SC	<CKENCL>,<+>,<REMAINDER OVER EVEN K AMOUNT>
	.ASCIZ	"+"		;
	.EVEN			;
62$:	JSR	R0,CKTSTR	;
	.ASCIZ	"KW (DECIMAL)"<15><12>
	.EVEN			;
	BR	70$		;
				;
	65$:	CK11SC	0,<CRLFTAB>	;FEED LINE, SPACE OVER
		.ASCIZ	"	"	;
		.EVEN			;
		ADD	R3,R1		;ACCUMULATE TOTAL BLOCKS TO DATE
		CLR	R3		;CLEAR FOR NEXT TIME
		JSR	PC,CKTOCT	;TYPE R0 FOR START BIAS
		TST	R0		;SKIP LEADING ZEROS IF ZERO
		BEQ	66$		;
		JSR	R0,CKTSTR	;ADD ZEROS FOR FULL ADDRESS
		.ASCIZ	"00"		;
		.EVEN			;
	66$:	JSR	R0,CKTSTR	;
		.ASCIZ	" - "		;
		.EVEN			;
		MOV	KISAR5,R0	;GET END OF BLOCK ADDRESS BIAS
		DEC	R0		;BACK TO LAST GOOD BIAS
		JSR	PC,CKTOCT	;
		JSR	R0,CKTSTR	;
		.ASCIZ	"77"		;
		.EVEN			;
		RTS	PC		;
					;
70$:				;
	    .ENDC ;NDF M$$MGE
	FALLR	CKCOR		;
;EDIT PAGE BREAK (FF)
.SBTTL		CHECK MEMORY - SLIDING BIT PATTERN
;
; PERFORM A SIMPLE READ/WRITE MEMORY TEST -
;THE PATTERN USED IS A SLIDING BIT, WITH THE
;BIT IN EACH OF THE 16 BIT POSITIONS AND THE
;LAST PATTERN BEING ALL 0'S.
;
CKCOR:
	    .IF NDF M$$MGE
	CLR	R0		;FIRST ADR TO CHECK
	MOV	#10$,R1		;LIMIT TO CHECK
				;CHECK IN TWO PIECES, SKIPPING
				;  THE AREA OF THE SUBROUTINE,
				;  SO AS NOT TO CLOBBER OURSELVES
	JSR	PC,10$		;CHECK LOW CORE
	MOV	#CKMPAR,R0	;BEGIN CHECKING HERE NOW
	MOV	PHYLIM,R1	;AND STOP HERE
	JSR	PC,10$		;
	JSR	R0,CKTCRL	;PRINT AMOUNT OF CORE
	.ASCIZ	\   \		;
	.EVEN			;
	MOV	PHYLIM,R0	;GET AMOUNT
	JSR	PC,CKTOCT	;PRINT IT
	JSR	R0,CKTSTR	;FOLLOWED BY MSG:
	.ASCIZ	\ BYTES OF UNMAPPED MEMORY\
	.EVEN			;
	BR	CKMPAR		;ALL OK, SKIP TO PARITY CHECKER
	    .IFF
	JSR	R0,CKTCRL	;
	.ASCIZ	"MAPPED PHYSICAL MEMORY TEST..."
	.EVEN			;
	CLR	KISAR5		;START AT LOWEST POSSIBLE ADDRESS
;;;;	MOV	#PD.PLF!<6*PD.AC0>,KISDR5 ;FULL PAGE, R/W ACCESS (SET ALREADY)
	MOV	#80$,NXMVEC	;SET UP BUS ERROR VECTOR
	CKCPSZ	= 1024.		;SET UP SIZE OF PAGE TO CHECK
	CLR	R1		;
8$:	MOV	R1,R0		;SET UP POINTER, CONSIDERING NON-ZERO START
	NEG	R0		;CHANGE NEGATIVE WORD COUNT
	ASL	R0		;  TO POSITIVE BYTE ADDRESS OFFSET
	ADD	#PAGE5,R0	;MAP THROUGH APR5
	ADD	#CKCPSZ,R1	;SET UP COUNT TO TEST
	JSR	PC,10$		;CALL CHECKER FOR DEFINED PAGE
	ADD	#CKCPSZ/BSFACT.,KISAR5 ;UP MAPPING REG TO NEXT PAGE
	CMP	KISAR5,PHYLIM	;PAST ALL OF PHYSICAL MEMORY?
	BLOS	8$		;NOT YET
	JSR	R0,CKTCRL	;ADVERTISE COMPLETION
	.ASCIZ	"		...COMPLETE"<15><12>
	.EVEN			;
	BR	CKMPAR		;
				;
80$:				;THIS TRAP HANDLER IS NEEDED ONLY IF THERE
				;  CAN BE HOLES IN THE PHYSICAL MEMORY
	CMP	(SP),#15$	;EXPECTED TRAP FROM CHECKER?
	BEQ	82$		;OKAY
	CK11SC	<CKEPC!CKEMSG>,<BAD NXM TRAP IN MEM CHK>
	.ASCIZ	"BAD NXM TRAP IN MEMORY CHECKER"<377>
	.EVEN			;
	BR	82$		;
82$:	MOV	#40$,(SP)	;SET RECOVERY ADDRESS
	RTI			;RECOVER
	    .ENDC ;NDF M$$MGE
.PAGE
; MEMORY CHECKER SUBROUTINE, CALLED FROM ABOVE, AND SKIPPED AROUND INLINE
;
1$:	.WORD	0		;LOCAL LOWER LIMIT WORD
10$:	MOV	#100000,R2	;SET UP TEST PATTERN
	MOV	(R0),R3		;SAVE CONTENTS OF OBJECT LOCATION
15$:				;LEGAL TRAP OCCURS HERE
	MOV	#-1,1$		;SET LIMIT WORD NON-ZERO
	CLR	(R0)		;CLEAR OBJECT WORD
	TST	1$		;REACHED LOWER LIMIT?
	BNE	20$		;NO, CONTINUE WITH TEST
				;YES, SET VALUES TO SKIP TESTING THIS CODE AREA
	ADD	#60$-1$,R0	;POINT PAST THIS CODE
	SUB	#<60$-1$>/2,R1	;ADJUST COUNT FOR SKIPPING TEST
	BGT	10$		;NO PAGE BREAK RESULTED, RESUME TEST
	RTS	PC		;CODE COVERS PAGE BREAK, RETURN R1 LE ZERO
				;
20$:				;
22$:	MOV	R2,(R0)		;STUFF CURRENT PATTERN
	COM	(R0)		;INVERT IT
	COM	(R0)		;AND BRING IT BACK
	CMP	(R0),R2		;DID IT SURVIVE?
	BEQ	30$		;YES
	CKSERR	R2,<(R0)>,R0	;SAVE GD,BD,ADR
	CK11SC	<CKEMSE!CKEPC!CKEGB>,<CKMG01>,<MEMORY ERROR>,<S..MEM>
	BR	30$		;
30$:	ASL	R2		;ADVANCE PATTERN
	BNE	22$		;REPEAT UNTIL R2 IS ZERO
	BCS	22$		;  AND EVEN THEN, DO IT ONCE MORE
	MOV	R3,(R0)		;RESTORE RIGHTFUL DATA
	COM	(R0)		;BLAP IT, TOO
	COM	(R0)		;  BACK AND FORTH
	CMP	(R0)+,R3	;CHECK FOR SURVIVAL AND ADVANCE POINTER
	BEQ	40$		;OKAY
	CKSERR	R3,<-(R0)>,R0	;SAVE GD,BD,ADR
	CK11SC	<CKEMSE!CKEPC!CKEGB>,<CKMG01>,<MEMORY ERROR>,<S..MEM>
	BR	40$		;
40$:	SOB	R1,10$		;DO OVER THE WHOLE DEFINED LIMIT OF THE PAGE
60$:	RTS	PC		;THEN RETURN
.PAGE
; CHECK THE MEMORY PARITY OPTION
;
CKMPAR:					;START CHECKING CORE HERE
.IF EQ <PDP11-40.>
	MOV	#N.MM11,CKDNAM		;SAVE NAME OF "DEVICE"
	CLR	CKDEVN			;"UNIT" IS 0
	MOV	#MP.REG,R1		;OPTION REGISTER
	MOV	R1,CHKCHR+CKDA		;SAVE ADR IN CASE NEED TO TYPE IT
	MOV	NXMVEC,-(SP)
	MOV	#MP.VEC,CHKCHR+CKDV	;VECTOR
 FOR INTERRUPTS
	MOV	#60$,NXMVEC		;IN CASE PARITY OPTION NOT INSTALLED
	CLR	MP.REG			;TRY TO CLEAR MEMORY PARITY REGISTER
	MOV	@P,NXMVEC		;RESTORE TRAP VECTOR
	JSR	R5,CHKBIT		;CHECK READ/WRITE BITS
	107745
;NOW CHECK INTERRUPTS FROM PARITY CONTROL
; THIS IS DIFFICULT CUZ SETTING MP.ENB & MP.ERR WON'T CAUSE INTERRUPT
	CLR	R0			;VECTOR WE TOOK WILL APPEAR HERE
	MOV	#MP.WWP,@R1		;WE WANT TO WRITE WRONG PARITY
	MOV	CKMPAR,CKMPAR		;WRITE A BAD WORD
;
	CLR	@R1			;BUT ONLY ONE WORD !
	TST	CKMPAR			;TRY FOR AN INTERRUPT
	NOP				;IN CASE SLOW
	TST	R0			;SEE IF WE GOT ONE
	BEQ	32$
	CK11SC	<CKEMSE!CKEDID!CKEPC>,CKMG07,<INTERRUPTED WHEN NOT ENABLED>
32$:	MOV	#MP.ENB,@R1		;NOW LETS GET THE INTERRUPT
	TST	CKMPAR
	CLR	@R1			;DISABLE FURTHER INTERRUPTS
	MOV	CKMPAR,CKMPAR		;WRITE BACK RIGHT
	TST	R0			;DID WE GET THE INTERRUPT ?
	BNE	34$
	CK11SC	<CKEDID!CKEMSE!CKEPC>,CKMG04,<INTERRUPT DID NOT OCCUR>
	BR	80$
;
34$:	CMP	R0,CHKCHR+CKDV		;WAS INTERRUPT RIGHT?
	BEQ	36$			;YES.
	CKSERR	<CHKCHR+CKDV>,R0,<#CKMPAR>	;GD,BD,ADR
	CK11SC	<CKEMSE!CKEDID!CKEPC!CKEGB>,CKMG05,<interrupted to wrong vector>
	BR	80$			;DONE.
;
.PAGE
; COME HERE IF PARITY OPTION IS PRESENT AND WORKING
;
36$:	JSR	R0,CKTCRL		;PRINT MESSAGE ABOUT IT
	.ASCIZ	\     MF11-UP\
	.EVEN
	MOV	#MP.ENB,MP.REG		;ENABLE PARITY ERRORS
	BR	80$			;ALL DONE.
;
;HERE IF WE GET A BUS TRAP WHILE ACCESSING THE PARITY CONTROL REG
60$:	MOV	(SP)+,(SP)+		;CLEAN OFF STACK
	CK11SC	<CKEDID!CKEPC!CKEMSE>,CKMG06,<not found>
;
.IF DF MP.ARM
	MOV	#402,MP.ARM		;MP.ARM CONTAINS A MOV #MP.ENB,MP.REG;
					; THIS TURNS IT INTO A BR .+6
.ENDC
80$:	MOV	(SP)+,NXMVEC
;
.ENDC;.IF EQ <PDP11-40.>
.PAGE
; SEE IF ROM = BM873 OR M9301 IS PRESENT
;
	    .IF DF FT.ROM
	    .IF NE FT.ROM
CK.ROM:	MOV	NXMVEC,-(SP)		;SAVE BUS TRAP VECTOR
	MOV	#20$,NXMVEC
	TST	ROMADR			;IS ROM REALLY HERE ?
	BR	90$			;YES
;
;HERE BECAUSE ROM NOT PRESENT
20$:	CLR	GO.ROM			;MAKE JMP ROMADR = HALT
	MOV	(SP)+,(SP)+		;CLEAN OFF STACK
;
90$:	MOV	(SP)+,NXMVEC
	    .ENDC;NE FT.ROM
	    .ENDC;DF FT.ROM
;EDIT PAGE BREAK (FF)
.SBTTL		CHECK KW11-L HDW
;
; BE SURE CLOCK IS PRESENT AND TICKS
;
CHKCLK:	MOV	#N.KW.L,CKDNAM		;SET UP FOR NAME
	BIC	#CKFIDT,CHKFLG		;SO WE PRINT DEV ID
	MOV	#CLKWRD,R4		;SET UP DEV ADR
	MOV	R4,CHKCHR+CKDA		;SET UP DEVICE ADR
	MOV	#CLKVEC,CHKCHR+CKDV	;SET UP VECTOR ADR
	CLR	CKDEVN			;DEVICE NUMBER
	MOV	#20$,NXMVEC		;SET BUS TRAP IN CASE CLOCK IS NOT PRESENT
	TST	(R4)			;TRAP IF NOT INSTALLED
	MOV	#CKBUST,NXMVEC		;WHERE TO GO ON BUS TRAP
	MOV	CLKVEC,-(SP)		;SAVE WHERE TO GO ON INT
	MOV	#80$,CLKVEC		;SETUP INTERRUPT VECTOR
	MOV	#3,CHKTIM		;TIME 3 TICKS
	CLR	PS			;LET INTERRUPTS HAPPEN
	MOV	#KW.INE,(R4)		;ENABLE THE CLOCK
	BEQ	15$			;IF COUNTED OUT ALREADY EVIL
	CLR	R0			;INITIALIZE WATCHDOG COUNTER
10$:	TST	CHKTIM
	BEQ	CKCLK9			;BRANCH IF TIMED OUT ALREADY
	SOB	R0,10$
	CK11SC	<CKEPC!CKEDID>,<Slow>,<NO RESPONSE FROM KW11>
	.ASCIZ	\Slow\<377>
	.EVEN
	BR	CKCLK9			;
15$:	CK11SC	<CKEPC!CKEDID>,<Fast>,<KW11 TICKING TOO FAST>
	.ASCIZ	\Fast\<377>
	.EVEN
	BR	CKCLK9			;
20$:	CK11SC	<CKEPC!CKEDID>,<Not Present>,<CAN'T ACCESS KW11>
	.ASCIZ	\Not Present\<377>
	.EVEN
	BR	CKCLK9			;
;
; KW11 INTERRUPT HANDLER
;
80$:	DEC	CHKTIM		;COUNT OUT TIMER
	BNE	90$		;
	CLR	(R4)		;TURN OFF CLOCK
90$:	RTI			;DISMISS INTERRUPT
				;
CHKTIM:	.WORD	0		;
CKCLK9:	SPL	7		;SET TO LEVEL 7
	MOV	#KW.INE,(R4)	;ENABLE INT
	MOV	(SP)+,CLKVEC	;RESTORE WHERE TO GO ON INT
	JSR	R5,CHKINL	;FIND THE INT LEVEL
	-1			;DELAY TO WAIT FOR INT
	BIC	#KW.INE,CLKWRD	;DISABLE CLK INTS
	JSR	R0,CKTCRL	;INDICATE CLOCK PRESENT
	.ASCIZ	\KW11-L checked\
	.EVEN			;
	JSR	PC,CKAKW1	;CALL TO MAIN FOR CLOCK
				;
	FALLR	.		;FALL INTO WHATEVER COMES NEXT
.PAGE
.SBTTL		CHECK DL10 HDW
;
CKDL10:
	    .IF NE FTDL10	;IF DOESN'T HAVE A DL10,DON'T CHECK IT
	MOV	DL10AD,R4	;IF "DL10AD" IS NON 0 A DL10 IS PRESENT
				; AND R4 WILL BE LOADED WITH BASE ADR
	BEQ	10$		;BRANCH IF WE DO NOT
	BIC	#CKFIDT,CHKFLG	;SO WE PRINT DEV ID
	MOV	#CKND10,CKDNAM	;DEVICE NAME
	CLR	CKDEVN		;DEVICE NUMBER
	MOV	R4,R1		;PUT DEVICE ADDR FOR CHKBIT
	MOV	R4,CHKCHR+CKDA	;PUT IN CHARACT TABLE FOR ERROR REPORTING
	JSR	R5,CHKBIT	;CHECK THE FOLLOWING BITS
	DL.B00!DL.B01!DL.INE!DL.ERE
	JSR	R5,CHKDLX	;CHECK SET/CLEAR OF
	DL.WCO			;WORD COUNT OVERFLOW
	JSR	R5,CHKDLX	;CHECK SET/CLEAR OF
	DL.PAR			;PARITY ERROR
	JSR	R5,CHKDLX	;CHECK SET/CLEAR OF
	DL.NXM			;NON EX MEM
	JSR	R5,CHKDLX	;CHECK SET/CLEAR OF
	DL.11I
8$:	MOV	#DL.B01,(R4)	;SET DL10 FOR LEVEL 5
	MOV	#DL.VEC,CHKCHR+CKDV;PUT DEVICE VECTOR IN TABLE FOR CKINT
	$CKINT	R4,R4,DL.INE,DL.11I,DL.11C
	$CKINT	R4,R4,DL.ERE,<DL.PAR!DL.NXM!DL.WCO>,<DL.CNX!DL.CPE!DL.CWC>
	JSR	R0,CKTCRL	;NOTE PRESENCE OF DL10
	.ASCIZ	\     DL10\
	.EVEN
10$:
	    .ENDC ;.IF NE FTDL10
;EDIT PAGE BREAK (FF)
.SBTTL		DEVICE SCAN AND CHECK
;
;THE SAME ROUTINE IS USED FOR FLOATING AND FIXED DEVICES
;HOWEVER FOR FIXED DEVICES THE VECTOR MULTIPLE MUST BE 0
;  *** WARNING: ***  CKCDEV IS BOTH CODE AND DATA BASE.
;DO *NOT* PUT ANYTHING OTHER THAN "DEVICE" MACROS BETWEEN CKCDEV AND CKCEND!
;
; INVOCATION:
;	DEVICE	A,MAXN,VI,HI,VM,NAM,FV
;
;	ARG	A	;DEVICE ADDRESS OR 0 IF FLOATING DEVICE
;	ARG	MAXN	;MAXIMUM NUMBER OF DEVICES
;	ARG	VI	;VECTOR INCREMENT
;	ARG	HI	;HARDWARE INCREMENT
;	ARG	VM	;VECTOR MULTIPLE
;	ARG	NAM	;DEVICE NAME ABBREVIATION
;	ARG	FV	;FIRST VECTOR ADR (FIXED DEV ONLY)
;
	JSR	R0,CKTCRL		;
	.ASCII	<12>"device scan report assumes"
.IIF DF CKSTD .ASCII	<15><12>"standard PDP-11 fixed and floating assignments"
	    .IF DF CKDN2X
	    .IF NE CKDN2X&B0
	.ASCII	<15><12>"       DN20"
	    .ENDC
	    .IF NE CKDN2X&B1
	.ASCII	<15><12>"       DN21"
	    .ENDC
	    .IF NE CKDN2X&B5
	.ASCII	<15><12>"       DN25"
	    .ENDC
	.ASCII	" fixed assignments (no floating)"
	    .ENDC ;DF CKDN2X
	.BYTE	0
	.EVEN				;
;
;
CKCDEV:					;FIXED ADDRESS, FIXED VECTOR DEVICES
CHKCD:	DEVICE	CD.STS,1,0,0,0,CD,CD.VEC	;CD20(CD11)
			CKCADD=.-CKCDEV			;SIZE OF "DEVICE" BLOCK
CHKCR:	DEVICE	CR.STS,1,0,0,0,CR,CR.VEC	;CR11
	DEVICE	KG.STS,8.,0,10,0,KG,0		;KG11
	DEVICE	LE.STS,2,-10,10,0,LE,LE.VEC	;LP11
	DEVICE	LP0STS,2,-4,20,0,LP,LP.VEC	;LP20
	DEVICE	PP.STS,1,0,0,0,PP,PP.VEC	;PP11(PC11)
	DEVICE	PR.STS,1,0,0,0,PR,PR.VEC	;PR11(PC11)
	DEVICE	TC.STS,1,0,0,0,TC,TC.VEC	;TC11
	DEVICE	TM.STS,1,0,0,0,TM,TM.VEC	;TM11
	DEVICE	177446,1,0,0,0,RC,210		;RC11
	DEVICE	177460,1,0,0,0,RF,204		;RF11
	DEVICE	176700,1,0,0,0,RH,254		;RH11
CHKRP:	DEVICE	176710,1,0,0,0,RP,254		;RP11-C
	DEVICE	177500,1,0,0,0,TA,260		;TA11
	DEVICE	177404,1,0,0,0,RK,220		;RK11
	DEVICE	177170,1,0,0,0,RX,264		;RX11
	DEVICE	172540,1,0,0,0,KW.P,104		;KW11-P
;;;;	DEVICE	DS.DVA,1,20,10,0,DS,DS.VEC	;DS11
CHKDTE:	DEVICE	174440,4,-4,40,0,DTE2,774	;DTE20
	    .IF DF CKSTD		;STANDARD FLOATING ASSIGNMENTS
					;FIXED ADDRESS, FLOATING VECTOR DEVICES
	DEVICE	174770,32.,10,-10,10,DP,0	;DP11
	DEVICE	175200,64.,4,10,4,DN,0		;DN11
	DEVICE	170500,16.,4,10,10,DM,0		;DM11BB
	DEVICE	172600,16.,4,10,4,R6,0		;PA611RDR
	DEVICE	172700,16.,4,10,4,P6,0		;PA611PNCH
	DEVICE	175610,16.,10,10,10,DL.E,0	;DL11-E
.IIF DF SY0880	DEVICE	177776,1,10,0,10,NL,0	;(NULL DEVICE, VECTOR SPACER)
					;FULLY FLOATING DEVICES
	DEVICE	0,16.,10,10,10,DJ,0		;DJ11
	DEVICE	0,16.,10,20,10,DH,0		;DH11
	DEVICE	0,16.,10,10,10,DQ,0		;DQ11
	DEVICE	0,16.,10,10,10,DU,0		;DU11
.IIF DF SY0880	DEVICE	0,1,10,10,10,NL,0	;(NULL DEVICE, ADDRESS SPACER)
	DEVICE	0,16.,10,10,10,DUP,0		;DUP11
.IIF DF SY0880	DEVICE	0,1,10,10,10,NL,0	;(NULL DEVICE, ADDRESS SPACER)
.IIF DF SY0880	DEVICE	0,1,10,10,10,NL,0	;(NULL DEVICE, ADDRESS SPACER)
	DEVICE	0,16.,10,10,4,DMC,0		;DMC11
	DEVICE	0,3.,10,10,4,KMC,0		;KMC11
	    .ENDC ;DF CKSTD
						;
	    .IF DF CKDN2X		;-20 FRONT END CONFIGURATIONS
		.IF NE CKDN2X&B0	;DN20
	DEVICE	160540,3,10,10,0,KMC,540	;KMC11
	DEVICE	160300,12.,10,10,0,DUP,570	;DUP11
	DEVICE	175630,1,10,10,0,DL.E,740	;DL11-E (DN20 #1)
	DEVICE	175640,1,10,10,0,DL.E,730	;DL11-E (DN20 #2)
	DEVICE	175650,1,10,10,0,DL.E,720	;DL11-E (DN20 #3)
		.ENDC ;NE CKDN2X&B0
		.IF NE CKDN2X&B1	;DN21
	DEVICE	160740,4,10,10,0,DMC,670	;DMC11
		.ENDC ;NE CKDN2X&B1
		.IF NE CKDN2X&B5	;DN25
	DEVICE	160640,3,10,10,0,KMC,300	;KMC11
	DEVICE	160010,16.,10,10,0,DZ,340	;DZ11
		.ENDC ;NE CKDN2X&B5
	    .ENDC ;DF CKDN2X
						;
CKCEND:					;END OF DEVICES TO CHECK
.PAGE
.SBTTL		CHK11 COMPLETION
;
CHK.90:	JSR	R0,CKTCRL	;
	.ASCIZ	<12>"	CHK11 complete"<15><12><12>
	.EVEN			;
	MOV	#CK.BUF,R0	;SEND A BLANK
	JSR	PC,CKBFSH	;  MESSAGE TO REMOTE
	CLR	@#6		;SET UP HALT TRAP
	MOV	#6,@#4		;  FOR NEXT PROGRAM
	MOV	(SP)+,KISDR6	;RESTORE PAGE 6
	MOV	(SP)+,KISAR6	;  MAPPING REGISTERS
	MOV	(SP)+,R5	;RESTORE
	MOV	(SP)+,R4	;  CALLER'S
	MOV	CK.DMC,R1	;  REGISTERS
	MOV	CK.CSP,SP	;RESTORE CALLER'S SP
	JMP	@CK.CAL		;RETURN TO CALLER
.SBTTL	END OF CHK11 MAINLINE
.PAGE
.SBTTL	GENERAL SUBROUTINES
;**** GOT RID OF ALL THE STANDARD CHK11 VECTOR SETUP HERE ****;
;**** AFTER ALL, THIS IS ONLY THE TERTIARY LOADER...      ****;
.SBTTL		LOOK FOR AND CHECK SYSTEM DEVICES
;
; CALLING SEQUENCE (GENERATED BY MACRO "DEVICE"):
;	JSR	R5,CHKDEV
;	(OFFSET
;	  NAME)
;	D.BADR	.WORD	ADDRESS OF 1ST DEVICE REGISTER
;	D.MAXL	.BYTE	MAX # OF DEVICES TO SEEK
;	D.VINC	.BYTE	VECTOR INC
;	D.HINC	.BYTE	HDW INC
;	D.VMUL	.BYTE	1ST VEC MULTIPLE
;	D.CNTP	.WORD	<ADR OF NUMBER OF DEVICES OR ZERO>
;	D.NAMP	.WORD	<ADR OF .ASCIZ \NAME\>
;	D.DIAG	.WORD	<ADR OF ROUTINE TO VERIFY OPERATION>
;	D.MAIN	.WORD	<ADR OF MAIN PROGRAM ROUTINE FOR DEVICE>
;	D.MPVC	.WORD	<ADR OF TABLE WHICH CONTAINS MAIN PROG VECTORS OR 0>
;	D.CNTF	.WORD	<# OF DEVICES FOUND>
;	D.FRSV	.WORD	<FIRST VECTOR FOUND>
;	D.PRIO	.WORD	<PI LEVEL>
;	D.FVFD	.WORD	<FIRST DEV VECTOR FOR FIXED TYPE DEV>
;	D.NEXT	(RETURN ADDRESS)
;
CHKDEV:			;
			;LOOK FOR AND COUNT PLAUSIBLE DEVICE TYPES
			;
	MOV	D.NAMP(R5),CKDNAM ;REMEMBER DEVICE NAME
	CLR	R2		;INITIALIZE COUNTER FOR DEVICES
				;GET DEVICE VECTOR
	MOV	CHKFLV,R3	;ASSUME FLOATING VECTOR
	TSTB	D.VMUL(R5)	;BUT SEE IF FIXED
	BNE	4$		;FLOATING VECTOR
	MOV	D.FVFD(R5),R3	;FIXED, GET PRE-ASSIGNED VECTOR
				;
4$:	MOV	(R5),R4		;GET HDW ADR FOR 1ST DEVICE
	BNE	6$		;ADDRESS IS NOT ZERO, HENCE FIXED DEVICE
				;DEV EXPECTS TO FLOAT, BUMP UP TO NEXT SLOT
	MOVB	D.HINC(R5),R1	;COMPUTE NEXT ADDRESS AS MULTIPLE OF HDW INC
	ADD	R1,CHKFLD	;
	DEC	R1		;
	BIC	R1,CHKFLD	;
	MOV	CHKFLD,R4	;COPY FOR USE
	MOV	R4,(R5)		;STUFF EXPECTED ADDRESS IN DEVICE TABLE
6$:				;
7$:	MOV	#20$,NXMVEC	;SET BUS TRAP VECTOR
	TST	(R4)		;CHECK TO SEE IF DEVICE IS PRESENT
	MOV	#CKBUST,NXMVEC	;IT'S THERE, SET BUS ERR VEC BACK
	TST	R2		;IS THIS THE FIRST OF ITS KIND ?
	BNE	15$		;NO
	CLR	D.CNTF(R5)	;YES, CLEAR NUMBER OF DEV FOUND
	CLR	D.FRSV(R5)	;CLEAR FIRST VECTOR ADR
;;;;	CLR	D.PRIO(R5)	;CLEAR BR LEVEL
	MOVB	D.VMUL(R5),R1	;GET ADDRESS MULTIPLE OF VECTOR
	BEQ	15$		;BRANCH IF FIXED VECTOR DEV
	DEC	R1		;ELSE COUNT UP VECTOR MOD VMUL
	MOV	R3,D.FVFD(R5)	;SAVE EXPECTED ADDRESS OF FIRST VECTOR
	ADD	R1,R3		;
	BIC	R1,R3		;
15$:	INC	R2		;COUNT DEVICE
	INC	D.CNTF(R5)	;COUNT DEVICE AND REMEMBER IT
	MOVB	D.VINC(R5),R1	;GET VECTOR INCREMENT
	ADD	R1,R3		;COMPUTE NEW VECTOR
	MOVB	D.HINC(R5),R1	;GET REG BLOCK INCREMENT
	ADD	R1,R4		;ADVANCE DEVICE ADR POINTER
	CMP	(R5),CHKFLD	;FLOATING DEVICE?
	BLOS	7$		;YES, KEEP LOOKING UNTIL GAP FOUND
	CMPB	R2,D.MAXL(R5)	;HAVE WE CHECKED AS MANY AS WE CAN EXPECT?
	BNE	7$		;NO, LOOP BACK FOR REST
	CMP	-(SP),-(SP)	;YES, FAKE A TRAP
				;WE HAVE FOUND AS MANY UNITS AS WE SOUGHT,
				;  OR WE HAVE TRAPPED ON FINDING FEWER
				;REPORT THE DEVICE COUNT
20$:	MOV	#CKBUST,NXMVEC	;RESET BUS ERROR VECTOR
	CMP	(SP)+,(SP)+	;POP OFF TRAP
	CMP	(R5),CHKFLD	;FLOATER?
	BHI	21$		;NO
	MOV	R4,CHKFLD	;YES, SAVE CURRENT ADDRESS AS GAP ADDRESS
	CMPB	R2,D.MAXL(R5)	;TOO MANY?
	BLOS	21$		;NO
	CK11SC	<CKEDID>,<Too many device units>
	.ASCIZ	"Too many units"
	.EVEN			;
21$:	TST	D.CNTP(R5)	;DO WE HAVE A REMOTE ADDRESS TO REPORT COUNT?
	BEQ	22$		;IF NOT, DON'T TRY
	MOV	R2,@D.CNTP(R5)	;YES, PUT NUMBER FOR SOMEONE TO FIND
22$:	MOV	R2,R0		;NUMBER OF DEVICES WE FOUND
	BNE	24$		;THERE ARE SOME
	.IF DF CKNODV
	JSR	PC,CKCRLF	;DO CR/LF
	JSR	R0,CKTSTR	;THERE AREN'T ANY
	.ASCIZ	"no"		;
	.EVEN			;
	BR	25$		;
	.IFF
	BR	40$		;AREN'T ANY - FORGET IT
	.ENDC
24$:	JSR	PC,CKCRLF	;DO CR/LF
	JSR	PC,CKTOCT	;TYPE OUT THE NUMBER
25$:	MOV	#70$,R0		;ASSUME FIXED ADDRESS DEVICE
	CMP	(R5),CHKFLD	;  BUT CHECK
	BHI	26$		;FIXED
	MOV	#72$,R0		;RATHER FLOATING
26$:	JSR	PC,CKTTXT	;SAY WHICH
	MOV	CKDNAM,R0	;GET ADR OF ASCIZ STRING
	JSR	PC,CKTTXT	;TYPE DEVICE NAME
	CMP	R2,#1		;HOW MANY ?
	BEQ	27$		;SINGULAR
	CK11SC	<CKENCL>,<'s>	;PLURAL
	.ASCIZ	\s\		;
	.EVEN			;
27$:	MOV	#74$,R0		;ADD TO DESCRIPTOR STRING
	CMP	R2,#1		;USE PROPER PREPOSITION
	BLOS	28$		;
	MOV	#73$,R0		;
28$:	JSR	PC,CKTTXT	;TYPE PREPOSITION
	MOV	(R5),R0		;GET EXPECTED DEVICE ADDRESS
	JSR	PC,CKTOCT	;TYPE IT OUT
				;THE CURRENT DEVICE UNITS HAVE BEEN SOUGHT
				;  AND COUNTED - PROCEED TO TEST ANY SO FOUND
	TST	R2		;WERE THERE ANY?
	BEQ	40$		;NO
	MOV	R3,-(SP)	;
	MOV	R4,-(SP)	;
	MOV	R2,-(SP)	;R2 MUST STAY ON TOP FOR COUNT
	CLR	CKDEVN		;CHECK UNIT 0 FIRST
	MOV	D.FVFD(R5),R3	;GET FIRST VECTOR FOR POSSIBLE FIXED
	MOV	R3,-(SP)	;
	JSR	R0,CKTSTR	;REPORT VECTOR ADDRESS
	.ASCIZ	", vector at"	;
	.EVEN			;
	MOV	(SP),R0		;
	JSR	PC,CKTBOC	;
	MOV	(SP)+,R3	;
	MOVB	D.VMUL(R5),R0	;GET VECTOR MULTIPLE
	BEQ	30$		;BRANCH IF FIXED
	MOV	CHKFLV,R3	;GET VECTOR FOR 1ST UNIT
	DEC	R0		;
	ADD	R0,R3		;
	BIC	R0,R3		;
30$:	MOV	(R5),R4		;GET HDW ADR FOR FIRST UNIT
	BNE	32$		;
	MOV	CHKFLD,R4	;FLOATING DEVICE
32$:	CLR	CHKCHR+CKPI	;ROUTINE WILL SET PI LEVEL
	MOV	D.DIAG(R5),R0	;ADR OF ROUTINE TO VERIFY DEVICE
	BEQ	34$		;BRANCH IF NO ROUTINE TO VERIFY
	BIC	#CKFIDT,CHKFLG	;HAVEN'T TYPED ID YET
	MOV	R4,CHKCHR+CKDA	;SAVE DEVICE ADDRESS
	MOV	R3,CHKCHR+CKDV	;SAVE VECTOR ADDRESS IN TABLE
	MOV	R4,R1		;PUT DEV ADR IN R1, MOST WILL USE IT
	CLR	CHKCHR+CKFLG	;CLR AND LET DEV ROUTINE SET FLAGS
	SPL	7		;MAKE SURE WE'RE AT LEVEL 7
	CMP	R4,CK.DMC	;IF THIS IS THE LOAD DEVICE,
	BEQ	33$		;  SKIP OVER DIAGNOSTICS FOR IT
	MOV	R5,-(SP)	;
	JSR	PC,(R0)		;CALL TO DEVICE CHECK
	MOV	(SP)+,R5	;
33$:	TST	D.FRSV(R5)	;SEE IF VECTOR ADR SET YET
	BNE	34$		;BRANCH IF SET
	MOV	CHKCHR+CKDV,D.FRSV(R5) ;SET FIRST VECTOR FOUND
;;;;	MOV	CHKCHR+CKPI,D.PRIO(R5) ;SET FIRST PI LEVEL FOUND
34$:	CMP	(R5),#DS.DVA	;DS11 ARE SPECIAL SO DON'T CALL MAIN HERE
	BEQ	35$		;BRANCH IF DS11
	MOV	#CHKCHR,R0	;POINT TO THE CHARACTERISTIC TABLE
	JSR	PC,@D.MAIN(R5)	;CALL TO MAIN PROGRAM
35$:	MOVB	D.VINC(R5),R0	;GET VECTOR INCREMENT
	ADD	R0,R3		;
	MOVB	D.HINC(R5),R0	;HDW INCREMENT
	ADD	R0,R4		;POINT TO NEXT REGISTER SET
	INC	CKDEVN		;ON TO NEXT DEVICE NUMBER
	CMP	CKDEVN,(SP)	;DONE ALL UNITS YET? (SET TO 177776 BY NULL DIAG)
	BLO	32$		;NO, NOT YET
	MOV	(SP)+,R2	;
	MOV	(SP)+,R4	;
	MOV	(SP)+,R3	;
40$:				;
	.REPT	0
		;;;;DISABLED CODE!!!
	SAVE	<R3,R4>
	CLR	R4		;FLAG NO MORE DEVICES
	JSR	PC,@D.MAIN(R5)	;CALL MAIN PROGRAM
	RESTORE	<R4,R3>
	.ENDR
;
;DONE CHECKING ALL DEVICE UNITS, UPDATE FLOATING VALUES AS REQ'D
;
	TSTB	D.VMUL(R5)	;FIXED VECTOR DEV?
	BEQ	50$		;YES
	MOV	CHKFLV,-(SP)	;NO, RESET FLOATING VECTOR
	MOV	R3,CHKFLV	;
	MOV	(SP)+,R3	;
	MOV	(R5),R0		;WAS THIS A FLOATING DEVICE ?
50$:	ADD	#D.NEXT,R5	;RETURN FOLLOWING TRAILING ARGS
	RTS	R5		;
				;
70$:	.ASCIZ	" Fixed "	;
	.EVEN			;
72$:	.ASCIZ	" Floating "	;
	.EVEN			;
73$:	.ASCIZ	" from "	;
	.EVEN			;
74$:	.ASCIZ	" at "		;
	.EVEN			;
;EDIT PAGE BREAK (FF)
.SBTTL		BIT BY BIT SET/CLEAR TEST
;
; CHECK WE CAN SET/CLEAR VARIOUS BITS
;
; CALL	MOV	#<ADR OF ASCIZ \NAME\>,CKDNAM
;	MOV	<DEVICE NUMBER>,CKDEVN
;	MOV	<DEVICE REGISTER ADDRESS>,R1
;	JSR	R5,CHKBIT
;	<ALL BITS TO TEST>
;
CHKBIT:	MOV	R0,-(SP)	;
	MOV	R2,-(SP)	;
	MOV	R5,R2		;USE R2 AS WORK REGISTER IN ROUTINE
	BIS	#BR7,PS		;DISABLE INTERRUPTS
	MOV	(R5),R0		;GET BITS TO CHECK
	BIC	R0,(R1)		;TRY AND CLEAR ALL OF THEM
	BIT	R0,(R1)		;SEE IF ALL OF THEM CLEARED?
	BEQ	1$		;BRANCH IF ALL CLEAR
	CLR	-(SP)		;WHAT THE RESULT SHOULD BE
	MOV	(R1),-(SP)	;PUT C(DEV REG) ON STACK
	MOV	R0,-(SP)	;BUT ONLY CERTAIN BITS ARE BAD CANDIDATES
	COM	(SP)		;GET RID OF ONES
	BIC	(SP)+,(SP)	; THAT WE'RE NOT INTERESTED IN
	MOV	R1,-(SP)	;SAVE THE DEVICE ADR
	CK11SC	<CKEMSE!CKEPC!CKEDID!CKEGB>,<CKMG02>,<BITS WOULD NOT CLEAR>
1$:	MOV	#1,R0		;START WITH B0 AND GO UNTIL B15 IS DONE
2$:	BIT	(R5),R0		;WANT THIS BIT CHECKED?
	BEQ	4$		;BRANCH IF NOT, AND MAKE NEW BIT
	BIS	R0,(R1)		;TRY TO SET THE BIT
	BIT	R0,(R1)		;SEE IF THE BIT SET
	BNE	3$		;BRANCH IF IT SET
	MOV	R0,-(SP)	;SAVE GOOD
	CLR	-(SP)		;GOOD SHOUD BE 0 FOR THAT BIT
	MOV	R1,-(SP)	;DEV ADR WHERE IT HAPPENED
	CK11SC	<CKEMSE!CKEPC!CKEDID!CKEGB>,<CKMG03>,<BIT WOULD NOT SET>
3$:	BIC	R0,(R1)		;NOW THAT ITS SET TRY TO CLEAR IT
	BIT	R0,(R1)		;SEE IF IT CLEARED
	BEQ	4$		;BRANCH IF IT CLEARED AND GET NEW BIT
	CLR	-(SP)		;GOOD SHOUD BE 0
	MOV	R0,-(SP)	;SINCE IT DIDN'T CLEAR THIS BIT IS BAD
	MOV	R1,-(SP)	;DEV ADR THAT FAILED
	CK11SC	<CKEMSE!CKEPC!CKEDID!CKEGB>,<CKMG02>,<BIT WOULD NOT CLEAR>
4$:	ASL	R0		;MAKE NEW BIT POSITION
	BNE	2$		;BRANCH IF THERE IS A BIT
	MOV	R2,R5		;RESTORE LINK REGISTER
	MOV	(SP)+,R2	;
	MOV	(SP)+,R0	;
	TST	(R5)+		;GO OVER BITS FOLLOWING JSR
	RTS	R5		;EXIT
.PAGE
.SBTTL		BIT SET/BIT CLEAR TEST FOR DL10
;
;ROUTINE TO CHECK DL10 BITS
;
	    .IF NE FTDL10
CHKDLX:	MOV	(R5)+,R0	;GET BIT TO CHECK
	BIS	R0,(R1)		;SET THE BIT IN THE DL10
	CMP	(R1),R0		;DID IT SET AND ONLY IT SET?
	BEQ	1$		;BRANCH IF OK
	CKSERR	R0,<(R1)>,R1	;GD, BD, ADR
	CK11SC	<CKEMSE!CKEPC!CKEDID!CKEGB>,<CKMG03>,<SET BIT BUT ITS NOT SET>
1$:	ASR	R0		;SHIFT RIGHT TO GET IT IN CLEAR POSITION
	BIS	R0,(R1)		;SET BIT TO CLEAR BIT
	TST	(R1)		;ALL BITS SHOULD BE CLEAR NOW
	BEQ	2$		;BRANCH IF THEY ARE
	CLR	-(SP)		;THE GOOD
	MOV	(R1),-(SP)	;THE BAD
	MOV	R1,-(SP)		;THE BAD ADR
	CK11SC	<CKEMSE!CKEPC!CKEDID!CKEGB>,<CKMG02>,<SETTING DIDN'T CLR BIT>
2$:	RTS	R5		;EXIT
	    .ENDC ;.IF NE FTDL10
.PAGE
.SBTTL		PRINT DEVICE ID ROUTINE
;
CKDIDT:	BIT	#CKFIDT,CHKFLG	;HAVE WE ALREADY TYPE DEVICE ID ?
	BNE	1$
	CK11SC	0,<? >
		.ASCIZ	<7>"	? "
		.EVEN
	MOV	CKDNAM,R0	;GET ASCIZ \DEVICE NAME\
	JSR	PC,CKTTXT	;TYPE DEVICE NAME
	CK11SC	<CKENCL>,< #>
		.ASCIZ	\ #\
		.EVEN
	MOV	CKDEVN,R0	;GET UNIT NUMBER
	JSR	PC,CKTOCT	;TYPE UNIT NUMBER
	CK11SC	<CKENCL>,<(Adr = >
		.ASCIZ	\(Adr = \
		.EVEN
	MOV	CHKCHR+CKDA,R0	;GET DEVICE ADDR
	JSR	PC,CKTOCT	;TYPE IT
	CK11SC	<CKENCL>,<)>
		.ASCIZ	\)\
		.EVEN
	BIS	#CKFIDT,CHKFLG	;REMEMBER WE TYPED DEVICE ID
1$:	RTS	PC
.PAGE
.SBTTL		ROUTINE TO FIND DEVICE INTERRUPT LEVEL
;
;CALL	JSR R5,CHKINL		;WITH DEVICE READY TO INT BUT
;				; WITH THE PS SET TO LEVEL 7.
;
CHKINL:	MOV	R0,-(SP)	;SAVE R0
	MOV	R1,-(SP)	;SAVE R1
	MOV	R2,-(SP)	;SAVE R2
	MOV	#BR6,R2		;START BY CHECKING LEVEL 6
1$:	MOV	(R5),R1		;GET TIME TO WAIT
	CLR	R0		;WILL BE SET BY INT ROUTINE IF INT
	MOV	R2,PS		;LOWER PS LEVEL
				;MOST REASONABLE INTERRUPTS WHICH OCCUR WILL
				;  DISPATCH THROUGH CKINT, RETURN THE VECTOR
				;  ADDRESS USED IN R0
2$:	TST	R0		;SEE IF INT YET
	BNE	10$		;NON 0 SAYS INTERRUPT HAPPENED
	SOB	R1,2$		;TIME AND WAIT
	SPL	7		;TIMED OUT SET LEVEL 7, LOWER AND TRY AGAIN
	SUB	#40,R2		;MAKE LEVEL LOWER BY 1
	BGE	1$		;BRANCH IF LEVEL 0 NOT CHECKED YET
	CK11SC	<CKEMSE!CKEDID!CKEPC>,<CKMG04>,<DEVICE NEVER INTERRUPTED>
	BR	3$		;EXIT
				;
10$:	CMP	R0,CHKCHR+CKDV	;SEE IF SAME AS WHAT IT SHOULD BE
	BEQ	11$		;BRANCH IF CORRECT VECTOR
	CKSERR	<CHKCHR+CKDV>,<R0>,<R4>
	CK11SC	<CKEMSE!CKEPC!CKEDID!CKEGB>,<CKMG05>,<WENT TO WRONG VECTOR>
				;
11$:	ADD	#40,R2		;MAKE THE DEVICE LEVEL
	MOV	R2,CHKCHR+CKPI	;SAVE LEVEL DEVICE INTERRUPTED AT
3$:	MOV	(SP)+,R2	;RESTORE R2
	MOV	(SP)+,R1	;RESTORE R1
	MOV	(SP)+,R0	;RESTORE R0
	TST	(R5)+		;SKIP OVER TIME DELAY CONSTANT
	RTS	R5		;RETURN WITH DEVICE LEVEL SAVED IN CHARACTERISTICS TABLE
;EDIT PAGE BREAK (FF)
.SBTTL		CHECK INTERRUPTS AND FIND DEVICE LEVEL
;
;ROUTINE TO CHECK INTERRUPTS AND FIND DEVICE LEVEL
;
; CALL (GENERATED BY MACRO "$CKINT"):
;	MOV	ENABLE ADR,R1
;	MOV	INT ADR,R2
;	JSR	R5,CKINT
;	TRAILING ARGS:
;		(NAME)	(PURPOSE)
;		I.ENAB	- ENABLE BIT
;		I.INTS	- INTERRUPT BITS
;		I.INTC	- SPECIAL CLEAR BITS
;		I.RTRN	- RETURN ADDRESS
;
CKINT:	MOV	R3,-(SP)
	MOV	R4,-(SP)
	CLR	CHKCHR+CKPI	;START WITH PI OF 0 (NO DEV)
	CLR	CKFLAG		;0 = PI LEVEL FOUND MUST BE PUT IN TABLE
				; NON 0 = CHECK PI LEVEL FOUND WITH TABLE
	MOV	#1,R4		;STARTING POSITION OF SLIDING INT BIT
CKINT1:	MOV	#BR7,R3		;START CHECKING AT THIS LEVEL
CKINT2:	MOV	R3,PS		;SET PS
	CLR	R0		;SET TO 0 SO IF INT HAPPENS WE KNOW IT
CKINT3:	BIT	R4,I.INTS(R5)	;IS THERE A BIT TO TEST?
	BNE	5$		;BRANCH IF BIT IN POSITION
	JMP	CKINT7		;MAKE NEW BIT POSITION
5$:	BIS	(R5),(R1)	;SET INTERRUPT ENABLE
	BIS	R4,(R2)		;SET INTERRUPT BIT
	NOP			;ALLOW 1 EXTRA INST TIME FOR INT
	SPL	7		;LET NO INT HAPPEN
	BIC	(R5),(R1)	;CLEAR INT ENABLE
	TST	I.INTC(R5)	;SEE IF SPECIAL CLEAR
	BEQ	7$		;BRANCH IF NOT
	BIS	I.INTC(R5),(R2)	;SPECIAL CLEAR
	BR	9$		;CONTINUE
7$:	BIC	I.INTS(R5),(R2)	;CLEAR INT BITS
9$:	TST	R0		;IF R0 IS NON 0 IT SHOULD BE THE
				; VECTOR ADR. IF 0 NO INT HAPPENED.
	BNE	10$		;BRANCH IF INTERRUPT
	SUB	#40,R3		;MAKE PS VALUE 1 LEVEL LESS
	BGE	CKINT2		;BRANCH IF NEW LEVEL OK
	CK11SC	<CKEMSE!CKEPC!CKEDID>,<CKMG04>,<DEVICE NEVER INTERRUPTED>
	BR	CKINTE		;EXIT
10$:				;INTERRUPT OCCURRED, CHECK IT OUT
	CMP	R0,CHKCHR+CKDV	;SEE IF WE WENT TO CORRECT ADR
	BEQ	13$		;BRANCH IF WE DID, R0 = VECTOR ADR
	CKSERR	<CHKCHR+CKDV>,R0,<R2>;GD,BD,ADR
	CK11SC	<CKEMSE!CKEPC!CKEDID!CKEGB>,<CKMG05>,<WENT TO WRONG VECTOR>
	BR	CKINTE		;EXIT
13$:	TST	CKFLAG		;MUST WE LOAD LEVEL OR CHECK IT?
	BNE	11$		;BRANCH IF JUST CHECK
	MOV	R3,CHKCHR+CKPI	;LOAD LEVEL JUST FOUND
	ADD	#40,CHKCHR+CKPI	;MAKE LEVEL OF DEVICE
	MOV	#-1,CKFLAG	;SET FLAG SO NEXT TIME WE CHECK LEVEL AS WELL
11$:	MOV	R3,R0		;GET PRESENT LEVEL
	ADD	#40,R0		;MAKE IT THE DEVICE LEVEL
	CMP	R0,CHKCHR+CKPI	;CHECK LEVEL AGAINST LAST TIME
	BEQ	CKINT6		;BRANCH IF LEVEL CHECKS
	CKSERR	<CHKCHR+CKPI>,R0,R4
	CK11SC	<CKEPC!CKEDID!CKEGB>,<Interrupt to Different BR Level>,<INTERRUPT TO DIFFERENT BR LEVEL>
	.ASCIZ	\Interrupt to Different BR Level\<377>
	.EVEN
	BR	CKINTE		;EXIT
CKINT6:	CLR	PS		;CHECK WITH LEVEL 0 AND
	CLR	R0		; NO INT ENABLE BITS SET
	BIS	R4,(R2)		;  AND INT BIT SET THAT NO INT OCCURRS
	NOP			;PAUSE
	NOP			;PAUSE
	SPL	7		;DON'T LET AN INT HAPPEN
	TST	R0		;SEE IF ONE HAPPENED
	BEQ	19$		;BRANCH IF NO INT
	CK11SC	<CKEMSE!CKEDID!CKEPC>,CKMG07,<INTERRUPT WHEN NOT ENABLED>
	BR	CKINTE		;EXIT
19$:	TST	I.INTC(R5)	;SEE IF SPECIAL CLEAR
	BEQ	22$		;BRANCH IF NOT
	BIS	I.INTC(R5),(R2)	;SPECIAL CLEAR  (DL10 FOR ONE)
	BR	24$		;CONTINUE
22$:	BIC	R4,(R2)		;CLEAR INT BITS
24$:	ASL	R4		;MAKE NEW BIT POSITION
	BEQ	CKINTE		;BRANCH IF DONE
	JMP	CKINT1		;TEST NEW BIT
CKINT7:	ASL	R4		;MAKE NEW INT BIT POSITION
	BEQ	CKINTE		;BRANCH IF NO NEW BIT POSITION
	JMP	CKINT3		;BRANCH IF NEW BIT POSITION
CKINTE:	ADD	#I.RTRN,R5	;FOR CORRECT RETURN
	MOV	(SP)+,R4	;
	MOV	(SP)+,R3	;
	RTS	R5		;RETURN
;
CKFLAG:	0
.PAGE
.SBTTL		GENERAL INTERRUPT FIELDER FOR CHK11
;
;WE GET HERE FROM ALMOST ANY INTERRUPT WHILE IN CHK11
; THIS WILL RETURN THE VECTOR ADDRESS IN R0 -
; THIS IS DISCERNED FROM THE CONDITION CODE BITS AND THE
; ADDRESS AT WHICH THE CODE IS ENTERED
;
CHKINT:
				;ENTRY FOR VECTORS 0-74
	MOV	PS,R0		;GET PROCESSOR STATUS
	JSR	PC,1$
	.WORD	0
		CHKISZ	= .-CHKINT ;CHKINT BLOCK SIZE
				;ENTRY FOR VECTORS 100-174
	MOV	PS,R0		;GET PROCESSOR STATUS
	JSR	PC,1$
	.WORD	100
				;ENTRY FOR VECTORS 200-274
	MOV	PS,R0		;GET PROCESSOR STATUS
	JSR	PC,1$
	.WORD	200
				;ENTRY FOR VECTORS 300-374
	MOV	PS,R0		;GET PROCESSOR STATUS
	JSR	PC,1$
	.WORD	300
				;ENTRY FOR VECTORS 400-474
	MOV	PS,R0		;GET PROCESSOR STATUS
	JSR	PC,1$
	.WORD	400
				;ENTRY FOR VECTORS 500-574
	MOV	PS,R0		;GET PROCESSOR STATUS
	JSR	PC,1$
	.WORD	500
				;ENTRY FOR VECTORS 600-674
	MOV	PS,R0		;GET PROCESSOR STATUS
	JSR	PC,1$
	.WORD	600
				;ENTRY FOR VECTORS 700-774
	MOV	PS,R0		;GET PROCESSOR STATUS
	JSR	PC,1$
	.WORD	700
	;-----------------------------------------------------------------
1$:	BIC	#^C17,R0	;SAVE ONLY CONDITION CODE BITS
	ASL	R0		;MULTIPLY BY 4 (4 BYTES PER VECTOR)
	ASL	R0		;
	ADD	@(SP)+,R0	;MAKES VECTOR ADR (POPS JSR RET ADR)
	MOV	#BR7,2(SP)	;DON'T TRAP AGAIN ON RETURN
	RTI			;
				;
CHKFLV:	.BLKW	1		;CURRENT FLOATING DEVICE VECTOR
CHKFLD:	.BLKW	1		;CURRENT FLOATING DEVICE ADR
.PAGE
.SBTTL	DEVICE DIAGNOSTICS
;
; THE FOLLOWING ROUTINES HAVE NAMES OF THE FORM X--11, WHERE -- IS
;   A DEVICE NAME (E.G. DH, DL, DTE2, KMC, ETC.) - THIS DEVICE NAME IS USED
;   IN THE MACRO "DEVICE" TO GENERATE A POINTER TO THE APPROPRIATE
;   DIAGNOSTIC ROUTINE - "DEVICE" CALLS CHKDEV, WHICH ACCESSES THE
;   TABLE GENERATED BY "DEVICE" CONTAINING THIS POINTER, AND USES
;   IT TO CALL THE PROPER DIAGNOSTIC
;
; DEVELOPERS: TRY TO KEEP THE DEVICE ROUTINE SETS IN
;   ALPHABETICAL ORDER BY DEVICE NAME (E.G., ...DL11-A, DL11-E,
;   DM11BB, DN11, ... DU11, DUP11, DZ11...) - ALSO NOTE THAT THE
;   THE DEVICE NAMES ARE THE ABBREVIATIONS USED IN THE MACRO NAMSTR
;
.PAGE
.SBTTL		CHECK CD20 HARDWARE
;
	    .IIF NDF FTCD20,FTCD20=0
	    .IF NE FTCD20
XCD11:				;
	MOV	#30$,NXMVEC	;SET A LOCAL BUS ERROR HANDLER
	TST	CDST2(R1)	;LOOK FOR SECONDARY STATUS REGISTER
	MOV	#CKBUST,NXMVEC	;IT'S THERE, THIS MAY BE A CD20 (NOT A CR11)
	MOV	CDBA(R1),-(SP)	;TO BE SURE,
	MOV	#-1,R0		;  FIND OUT IF WE CAN
	XOR	R0,CDBA(R1)	;  FIDDLE THE "CDBA" BITS
	CMP	(SP)+,CDBA(R1)	;  IF WE CAN'T,
	BEQ	40$		;  IT ISN'T A CD11/20
	XOR	R0,CDBA(R1)	;  IF WE DID, PUT THE BITS BACK
	BIS	#1,CHKCR+4	;MAKE CR11 TEST FAIL IF TRIED
	JSR	R5,CHKBIT	;R/W CHECK ON CD.STS
	.WORD	CD.IE!CD.XAD!CD.PAC
	TST	(R1)+		;UP TO CDCC
	JSR	R5,CHKBIT	;
	.WORD	ALLBTS		;
	TST	(R1)+		;UP TO CDBA
	JSR	R5,CHKBIT	;
	.WORD	ALLBTS		;
	MOV	R4,R1		;RESTORE CD.STS POINTER
	BIT	#CD.OFL,(R1)	;READER AVAILABLE?
	BNE	10$		;YES
	CK11SC	0,<not ready>	;
	.ASCIZ	"	CD20 off line"
	.EVEN			;
	RTS	PC		;
				;
10$:	MOV	#CD.PWC,(R1)+	;CLEAR READER
	MOV	#-1,(R1)+	;SET TO READ ONE COLUMN
	MOV	#160000,(R1)+	;  INTO A NON-EXISTENT LOCATION
	MOV	#CD.IE!CD.XAD!CD.GO,(R4) ;START READER
	CLR	R0		;SET TIMER FOR READ WAIT
15$:	BIT	#CD.ERR!CD.RDY,(R4) ;LOOK FOR ERROR OR DONE
	BNE	20$		;GOT ONE OF THEM
	SOB	R0,15$		;NOT YET
	CK11SC	<CKEPC!CKEDID>,<SLOW READ>
	.ASCIZ	"	CD20 time out on read"
	.EVEN			;
	RTS	PC		;
				;
20$:	JSR	R5,CHKINL	;CD20 SHOULD BE READY TO INTERRUPT
	.WORD	177777		;
	RTS	PC		;
				;
30$:	MOV	#CKBUST,NXMVEC	;RESTORE BUS ERROR VECTOR
	CMP	(SP)+,(SP)+	;POP TRAP
40$:	CK11SC	0,<NOT CD20>	;
	.ASCIZ	"	correction - reader is NOT a CD20"
	.EVEN			;
	RTS	PC		;
	    .ENDC ;NE FTCD20
;EDIT PAGE BREAK (FF)
.SBTTL		CHECK CR11 HARDWARE
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,XCR11
;
	    .IIF NDF FTCR11,FTCR11=0
	    .IF NE FTCR11
XCR11:
	MOV	CDBA(R1),-(SP)	;CHECK TO SEE
	MOV	#-1,R0		;  IF WE CAN
	XOR	R0,CDBA(R1)	;  FIDDLE THE BITS IN
	CMP	(SP)+,CDBA(R1)	;  THE BUFFER ADDRESS CSR
	BEQ	10$		;NO - READER IS REAL
	XOR	R0,CDBA(R1)	;YES - SET THE BITS BACK
	CK11SC	0,<NOT CR11>	;  AND COMPLAIN
	.ASCIZ	"	oops - reader is NOT a CR11"
	.EVEN			;
	RTS	PC		;
				;
10$:	BIS	#1,CHKCD+4	;MAKE CD20 TEST FAIL IF TRIED
	JSR	R5,CHKBIT	;CHECK HARDWARE BITS
	.WORD	CR.EJT!CR.INE	;
	BIT	#CR.BSY,(R4)	;SEE IF BUSY (MAYBE POWER OFF)
	BEQ	2$		;BRANCH IF COMMAND CAN BE GIVEV
	CK11SC	0,< CR11 not Rdy>
	.ASCIZ	\ CR11 not Rdy\
	.EVEN
	MOV	#CR.LVL,CHKCHR+CKPI ;GIVE DEFAULT LEVEL
	RTS	PC		;
				;
2$:	MOV	#CR.INE!CR.CFD,(R4) ;SET INT ENABLE AND READ
			; TO FORCE ANY KIND OF INT
	CLR	R0		;FOR TIMING OUT
1$:	BIT	#CR.ERR!CR.CDN,(R4) ;SEE IF AN INT CONDITION EXISTS
	BNE	3$		;IF NOT, THEN WAIT.
	SOB	R0,1$		;START TIMING OUT
	BIC	#CR.INE,(R4)	;DISABLE CR11 INT ENABLE
	CK11SC	<CKEPC!CKEDID>,<CR11 Timed Out>,<CR11 NOT RESPONDING>
	.ASCIZ	\CR11 Timed Out\
	.EVEN			;
	RTS	PC		;
				;
3$:	JSR	R5,CHKINL	;FIND INT LEVEL
	-1			;FOR TIME-OUT LOOP
	BIC	#CR.INE,(R4)	;DISABLE INT FOR CR11
	RTS	PC		;
	    .ENDC ;NE FTCR11
.PAGE
.SBTTL		CHECK DH11 HDW
.IIF NDF NDH11,NDH11=0	;BY DEFAULT NO DH11S
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,XDH11
;
	    .IIF NDF FTDH11,FTDH11=0
	    .IF NE FTDH11
XDH11:	MOV	R3,-(SP)	;SAVE REGISTER
	JSR	R5,CHKBIT	;CHECK RD/WRT BITS
	131177			;READ/WRITE BITS
	TST	(R1)+		;ADVANCE TO NXT REC CHAR REG
	TST	(R1)+		;ADVANCE TO LINE PARAMETER REG(XX4)
	JSR	R5,CHKBIT	;CHECK RD/WRT BITS
	177767			;READ/WRITE BITS
	TST	(R1)+		;ADVANCE TO CURRENT ADR REG(XX6)
	CLR	R2		;START CHECK AT LINE 0
1$:	JSR	R5,CHKBIT	;CHECK RD/WRT BITS
	-1			;READ/WRITE BITS
	INC	R2		;NEXT LINE TO CHECK
	CMP	R2,#17		;DONE
	BLE	1$		;CHECK LINES 0-17
	TST	(R1)+		;ADVANCE TO BYTE COUNT REG(X10)
	CLR	R2		;START CHECK AT LINE 0
2$:	JSR	R5,CHKBIT	;CHECK RD/WRT BITS
	-1			;READ/WRITE BITS
	INC	R2		;NEXT LINE TO CHECK
	CMP	R2,#17		;ALL LINES CHECKED?
	BLE	2$		;CHECK ALL 20 LINES
	TST	(R1)+		;ADVANCE TO BAR REG(XX12)
	TST	(R1)+		;ADVANCE TO BREAK REG(X14)
	JSR	R5,CHKBIT	;CHECK BITS
	-1			;READ/WRITE BITS
	TST	(R1)+		;ADVANCE TO SILO STATUS REG(X16)
	JSR	R5,CHKBIT	;CHECK READ/WRITE BITS
	77
	$CKINT	R4,R4,<DH.RIE!DH..MM>,<DH..RI>
	$CKINT	,,<DH.SIE!DH..MM>,<DH..SI>
	ADD	#4,CHKCHR+CKDV		;MAKE EXPECTED VECTOR FOR XMIT
	$CKINT	,,<DH.TIE>,<DH..TI>
	MOV	R3,CHKCHR+CKDV		;PUT VECTOR ADDRESS IN TABLE
					;
	    .IF NE NDH11		;DON'T CHECK HARDWARE NOT TO BE USED
CKDH1A:	MOV	R3,DHXMII		;ADR TO COME TO ON XMIT INT
	ADD	#4,DHXMII		;
	MOV	#CKBLK,R0		;LOAD A BUFFER WITH COUNT PATTERN
	MOV	#400,R1			;LOAD 400 CHARACTERS
	CLR	R2			;START WITH 0
1$:	MOVB	R2,(R0)+		;STORE THE COUNT PATTERN
	INCB	R2			;NEW PATTERN
	SOB	R1,1$			;BUFFER LOADED?
	CLR	R3			;START WITH LINE 0
	MOV	#1,R2			;LINE BIT  (LINE 0)
CKDH1B:	CLR	DHDATA			;FIRST RCV'D SHOULD BE 0
.IIF NDF NTRIB,NTRIB=0
	    .IF NE NTRIB
				;IF TRIBUTARY LINES IN USE
				;USE MINIMAL TEST TO AVOID INTERFERRENCE
				;WITH THE FUNCTIONAL STATIONS ON LINE
				;THE PROBLEM ARISES BECAUSE MAINTAINANCE
				;MODE ON THE DH11 DRIVES THE MODEM LINES!!!
	MOV	#-1,R1
	DEC	DHDATA
	MOVB	R1,CKBLK
	    .IFF
	MOV	#-400,R1
	    .ENDC	;.IF NE NTRIB
	BIS	#DH..MC,(R4)		;CLEAR THE DH
	BIS	#DH..MM!DH.SIE!DH.TIE!DH.RIE,(R4)	;ENABLE INTS
	BIS	R3,(R4)			;LOAD THE LINE NUMBER
	MOV	#B6!B8!B9!B10!B12!B13!DH.2SB!DH.CL8!DH.PEN!DH..OP,DH.LPR(R4)
					;SEL 8BIT,9600,PAR,ODD
	MOV	R1,DH.BCR(R4)		;LENGTH TO XMIT
	MOV	#CKBLK,DH.CAR(R4)	;ADR WHERE THE DATA IS
	MOV	#4,DH.SSR(R4)		;ALARM LEVEL TO 4
CKDH1E:	CLR	R0			;INT RETURNS ADR IN HERE
	CLR	R1			;TIMER
	MOV	R2,DH.BAR(R4)		;SET LINE ACTIVE
2$:	CLR	PS			;LEVEL TO 0 FOR INTS
	NOP				;LET AN INTERRUPT HAPPEN
	SPL	7			;DON'T LET ONE HAPPEN
	CMP	R0,CHKCHR+CKDV		;SEE IF RCV INT YET
	BEQ	4$			;BRANCH IF RCV INT
	CMP	R0,DHXMII		;SEE IF XMIT INT
	BEQ	5$			;BRANCH IF XMIT INT
	TST	R0			;SEE IF ANY INTERRUPT
	BEQ	3$			;BRANCH IF NO INTERRUPT
	CKSERR	<CHKCHR+CKDV>,R0,R3
	CK11SC	<CKEPC!CKEGB!CKEDID>,<Ill Int>,<ILLEGAL INT WHILE WAITING FOR DH11 INT>
	.ASCIZ	\Ill Int\<377>
	.EVEN
	JMP	CKDH1D			;DON'T TEST ANY MORE
3$:	SOB	R1,2$			;TIME-OUT
	CK11SC	<CKEPC!CKEDID>,<No Int>,<NO DH11 INTERRUPT>
	.ASCIZ	\No Int\<377>
	.EVEN
	JSR	PC,CKDHPL		;REPORT LINE NUMBER
	JMP	CKDH1D			;DON'T TEST ANY MORE
5$:	BIT	#DH.NXM,(R4)		;SEE IF NXM
	BEQ	16$			;BRANCH IF NO NXM
	CK11SC	<CKEPC!CKEDID>,<Xmit Nxm>,<TRANSMIT NXM ON DH>
	.ASCIZ	\Xmit Nxm\<377>
	.EVEN
	JSR	PC,CKDHPL		;REPORT LINE NUMBER
	BR	CKDH1D			;DON'T TEST ANY MORE
16$:	BIT	#DH..TI,(R4)		;BETTER HAVE XMIT INT
	BNE	17$			;BRANCH IF WE DO
	CK11SC	<CKEPC!CKEDID>,<Ill Xmit Int>,<INT TO XMIT BUT FOR NO REASON>
	.ASCIZ	\Ill Xmit Int\<377>
	.EVEN
	JSR	PC,CKDHPL		;REPORT LINE NUMBER
	BR	CKDH1D			;DON'T TEST ANY MORE
17$:	BIC	#DH..TI,(R4)		;CLEAR XMIT INT
	BR	CKDH1E			;
4$:	BIT	#DH..SI,(R4)		;SEE IF SILO OVERFLOW
	BEQ	CKDH1C			;BRANCH IF SILO HAD ROOM
	CK11SC	<CKEPC!CKEDID>,<Silo Full>,<SILO OVERFLOW>
	.ASCIZ	\Silo Full\<377>
	.EVEN
	JSR	PC,CKDHPL		;REPORT LINE NUMBER
	BR	CKDH1D			;DON'T TEST ANY MORE
CKDH1C:	BIC	#DH..RI,(R4)		;CLEAR RCV INT (MUST FOR MAINT MODE)
	MOV	DH.NRC(R4),R0		;GET STUFF FROM SILO
	BIT	#DH.DOV!DH..FE!DH..PE,R0	;SEE IF ANY ERROR BITS WITH DATA
	BEQ	7$			;BRANCH IF NO ERRORS WITH THE DATA
	MOV	DHDATA,-(SP)		;MAKE THE GOOD
	MOV	R3,-(SP)			;PUT LINE # IN
	SWAB	(SP)			;GET IT IN THE (LB)
	BIS	(SP)+,(SP)		;LINE # NOW IN GOOD
	BIS	#DH.VDP,(SP)		;GOOD INCLUDES VALID DATA PRESENT
	MOV	R0,-(SP)			;THE BAD
	MOV	R3,-(SP)			;THE LINE UNDER TEST
	CK11SC	<CKEGB!CKEPC!CKEDID>,<Data Err Bit Set>,<ERROR BITS WITH THE DATA>
	.ASCIZ	\Data Err Bit Set\<377>
	.EVEN
	BR	CKDH1D			;DON'T TEST ANY MORE
7$:	BIT	#DH.VDP,R0		;SEE IF VALID DATA
	BNE	8$			;BRANCH IF VALID DATA
	CK11SC	<CKEPC!CKEDID>,<Not Valid Data>,<NOT VALID DATA BIT SET>
	.ASCIZ	\Not Valid Data\<377>
	.EVEN
	JSR	PC,CKDHPL		;REPORT LINE NUMBER
	BR	CKDH1D			;DON'T TEST ANY MORE
8$:	BIC	#B15!B14!B13!B12,R0	;CLEAR DATA ERROR BITS
	SWAB	R0			;FOR CHECKING LINE #
	CMPB	R0,R3			;SEE IF LINE #OK
	BEQ	9$			;BRANCH IF IT IS
	MOV	R3,-(SP)			;LEGAL LINE NUMBER
	CLR	-(SP)			;0 FOR BYTE MOVE
	MOVB	R0,(SP)			;THE ILLEGAL LINE NUMBER
	MOV	R3,-(SP)			;LINE UNDER TEST
	CK11SC	<CKEGB!CKEPC!CKEDID>,<Ill Line Num>,<ILLEGAL LINE NUMBER>
	.ASCIZ	\Ill Line Num\<377>
	.EVEN
	BR	CKDH1D			;DON'T TEST ANY MORE
9$:	SWAB	R0			;FOR CHECKING THE DATA
	CMPB	R0,DHDATA		;SEE IF CORRECT DATA
	BEQ	10$			;BRANCH IF DATA OK
	MOV	DHDATA,-(SP)		;GOOD DATA
	CLR	-(SP)			;FOR BYTE MOVE
	MOVB	R0,(SP)			;THE BAD DATA
	MOV	R3,-(SP)			;THE LINE #
	CK11SC	<CKEGB!CKEPC!CKEDID>,<Data Err>,<DATA ERROR>
	.ASCIZ	\Data Err\<377>
	.EVEN
	BR	CKDH1D			;DON'T TEST ANY MORE
10$:	INCB	DHDATA			;NEW PATTERN EXPECTED
	BEQ	11$			;BRANCH IF LINE DONE
	JMP	CKDH1E			;
;
11$:
CKDH1D:	INC	R3			;NEW LINE NUMBER
	ASL	R2			;NEW BIT FOR NEXT LINE
	BEQ	CKDH1F			;BRANCH IF TEST ALL DONE
	JMP	CKDH1B			;
;
CKDHPL:	CK11SC	0,<		Line #>
	.ASCIZ	\		Line #\
	.EVEN
	MOV	R3,R0			;LINE NUMBER TO R0 FOR CALL
	JSR	PC,CKTOCT		;PRINT LINE NUMBER
	RTS	PC			;RETURN
;
	    .IFF ;NE NDH11
10$:	JSR	R0,CKTSTR
	.ASCIZ	\	SKIPPING TRANSMISSION CHECK\
	.EVEN
	MOV	#377+<<.+6-10$>/2>,10$	;SHUT OFF SKIPPING COMMENT
	    .ENDC ;NE NDH11
;
CKDH1F:	BIS	#DH..MC,(R4)		;MASTER CLEAR
	MOV	(SP)+,R3	;GET R3 BACK
	RTS	PC			;DH CHARACTER TEST DONE
DHDATA:	0
DHXMII:	0
	    .ENDC ;NE FTDH11
;EDIT PAGE BREAK (FF)
.SBTTL		CHECK DL11-A HDW
;
	    .IIF NDF FTDL1A,FTDL1A=0
	    .IF NE FTDL1A
XDL.A11:
	RTS	PC
	    .ENDC ;NE FTDL1A
.PAGE
.SBTTL		CHECK DL11-E HDW
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,XDL11
;
	    .IIF NDF FTDL1E,FTDL1E=0
	    .IF NE FTDL1E
XDL.E11:
	MOV	R3,-(SP)	;
	JSR	R5,CHKBIT	;CHECK READ/WRITE BITS
	000156			;
	TST	(R1)+		;ADVANCE TO RECEIVE DATA REGISTER
	TST	(R1)+		;ADVANCE TO TRANSMIT STATUS REGISTER
	JSR	R5,CHKBIT	;
	000105			;
	MOV	(SP)+,R3	;
	RTS	PC		;
	    .ENDC ;NE FTDL1E
.PAGE
.SBTTL		CHECK DM11BB HDW
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,XDM11
;
	    .IIF NDF FTDM11,FTDM11=0
	    .IF NE FTDM11
XDM11:	JSR	R5,CHKBIT		;CHECK FOLLOWING BITS
	DM.ALI!DM.DNE!DM..MM!DM.ENB!DM.IEN
	$CKINT	,R4,<DM.IEN>,<DM.DNE>
	JSR	PC,CKDMCS		;CLEAR SCAN AND CHECK IT CLEARED
	BIS	#DM.ENB,(R4)		;ENABLE SCAN
	BIT	#DM.BSY,(R4)		;SEE IF BSY SET
	BNE	1$			;BRANCH IF IT DID
	CK11SC	<CKEPC!CKEDID>,<Busy did not Set>,<BUSY DID NOT SET>
	.ASCIZ	\Busy did not Set\<377>
	.EVEN
1$:	JSR	PC,CKDMCS		;CLEAR SCAN AND CHECKED IT CLEARED
	RTS	PC
;
.IIF NDF DM.TIM,DM.TIM=40.		;DM11BB SETTLE TIME IN MEMORY CYCLES
;
CKDMCS:	MOV	#DM.DNE!DM..MM!DM.IEN!DM.ENB!DM.ALI,R2
					;BITS WHICH SHOULD GET CLEARED
	MOV	#<DM.TIM/5>,R0		;TIME OUT FOR BUSY
	BIS	#DM.SCN,(R4)		;CLEAR SCAN
5$:	BIT	#DM.BSY,(R4)		;SEE IF BUSY CLEAR YET
	BEQ	2$			;BRANCH IF IT IS
	SOB	R0,5$			;TIME OUT WAITING FOR BSY TO CLEAR
	CK11SC	<CKEPC!CKEDID>,<Busy did not Clear>,<CLEARING SCAN FAILED TO CLEAR BUSY>
	.ASCIZ	\Busy did not Clear\<377>
	.EVEN
2$:	BIT	R1,(R4)			;SEE IF THEY ARE ALL CLEAR
	BEQ	3$			;BRANCH IF THEY ARE ALL CLEAR
	MOV	(R4),R0			;GET DM11 STATUS
	COM	R2			;MASK OUT NON INTERESTING BITS
	BIC	R2,R0			;
	CLR	-(SP)			;GOOD
	MOV	R0,-(SP)			;BAD
	MOV	R4,-(SP)			;ADR
	CK11SC	<CKEGB!CKEPC!CKEDID>,<Clear Scan Error>,<CLR SCAN FAILED TO CLEAR A BIT>
	.ASCIZ	\Clear Scan Error\<377>
	.EVEN
3$:	RTS	PC
	    .ENDC ;NE FTDM11
.PAGE
.SBTTL		CHECK DN11 HDW
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,XDN11
;
	    .IIF NDF FTDN11,FTDN11=0
	    .IF NE FTDN11
XDN11:	JSR	R5,CHKBIT		;CHECK BITS
	007714				;READ/WRITE BITS
	$CKINT	,R4,<DN..IE!DN..ME>,<DN.DNE>
	RTS	PC
	    .ENDC ;NE FTDN11
.PAGE
.SBTTL		CHECK DP11 HDW
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,XDP11
;
	    .IIF NDF FTDP11,FTDP11=0
	    .IF NE FTDP11
XDP11:	JSR	R5,CHKBIT	;CHECK BITS
	3707			;READ/WRITE BITS
	TST	(R1)+		;ADV TO REC BUF/SYN REG
;;;;	JSR	R5,CHKBIT	;CHECK BITS
;;;;	000000			;READ/WRITE BITS
	TST	(R1)+		;ADV TO XMT STATUS REG
	JSR	R5,CHKBIT	;
	000143			;READ/WRITE BITS
;;;;	TST	(R1)+		;ADV TO XMT BUFFER
;;;;	JSR	R5,CHKBIT	;
;;;;	000000			;READ/WRITE BITS
	$CKINT	R4,R4,B6,B7	;
	RTS	PC		;
	    .ENDC ;NE FTDP11
.PAGE
.SBTTL		CHECK DQ11 HDW
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,XDQ11
;
	    .IIF NDF FTDQ11,FTDQ11=0
	    .IF NE FTDQ11
XDQ11:
	    .IF	NDF,FT.D75		;ONLY ASSEMBLE DQ IF NOT DC75
	JSR	R5,CHKBIT		;CHECK WE CAN SET BITS
	110373				;READ/WRITE BITS
	TST	(R1)+			;ADVANCE TO XMT REGISTER
	JSR	R5,CHKBIT		;CHECK WE CAN SET BITS
	101772				;READ/WRITE BITS
	TST	(R1)+			;ADVANCE TO ERR REGISTER
	JSR	R5,CHKBIT		;CHECK WE CAN SET BITS
	017477				;READ/WRITE BITS
	TST	(R1)+			;ADVANCE TO SHADOW REGISTERS
	JSR	R5,CHKBIT
	-1
;
;DETERMINE DQ11 INTERRUPT LEVEL
;
30$:	$CKINT	R4,R4,DQ.RIE,<DQ.RDP!DQ.RDS>
	MOV	CHKCHR+CKDV,-(SP)	;SAVE VECTOR
	ADD	#4,CHKCHR+CKDV		;MAKE VECTOR B
	CMP	(R1)+,(R2)+		;POINT TO XMIT REG
	$CKINT	,,<DQ.XIE>,<DQ.XDS!DQ.XDP>
	TST	(R2)+			;ADVANCE INT BIT POINTER TO ERR REG
	$CKINT	,,<DQ.EIE>,<DQ.VRC!DQ.XLE!DQ.RLE!DQ.XNX!DQ.RNX!DQ.XCL!DQ.RCL>
	MOV	(SP)+,CHKCHR+CKDV		;RESTORE VECTOR A VECTOR
;
;ENTRY BECAUSE DQ11 TRAPPED TO RIGHT LOCATION
; CHECK WE CAN CLEAR THE DATASET FLAG
;
32$:	MOV	#5,R0			;PATIENCE COUNTER ON DATASET FLAG
31$:	BIC	#DQ.DSF,2(R4)		;CLEAR DATASET FLAG
	CMP	(SP),(SP)			;TIME WASTER ONLY
	BIT	#DQ.DSF,2(R4)		;CHECK TO SEE IF DATASET FLAG STILL OFF
	BEQ	CHKDQE
	SOB	R0,31$
	CK11SC	<CKEDID!CKEPC>,<Can't Clr Dataset Flg>,< CAN'T CLEAR DATASET FLAG>
	.ASCIZ	\Can't Clr Dataset Flg\<377>
	.EVEN
.PAGE
;CHECK THAT ERROR BITS WORK
;
CHKDQE:	JSR	PC,CKDQCL		;CLEAR ENTIRE DQ
	MOV	#40,R2			;FIRST BIT TO TRY
1$:	BIS	R2,4(R4)		;SET AN ERROR BIT
	MOV	4(R4),R0		;GET ERR REG
	BPL	2$			;BRANCH IF B15 ERR NOT SET
	BIT	R2,R0			;SEE IF THE BIT SET
	BNE	3$			;BRANCH IF B15 SET AND ERR BIT SET
2$:	MOV	R2,-(SP)			;SAVE GOOD
	BIS	#B15,(SP)		; ALSO MUST INCLUDE BIT 15.
	JSR	PC,CKDQES		;PUT BAD AND REG # ON STACK
	CK11SC	<CKEDID!CKEPC!CKEGB>,<Bit not Set>,<CAN'T SET BIT>
	.ASCIZ	\Bit not Set\<377>
	.EVEN
3$:	BIC	R2,4(R4)		;CLEAR BIT JUST SET, SHOULD ALSO CLEAR B15.
	MOV	4(R4),R0		;SAVE RESULTS
	BMI	4$			;BRANCH IF B15 SET (IT SHOULDN'T BE)
	BIT	R2,R0		;SEE IF THE BIT IS CLEAR
	BEQ	5$			;BRANCH IF ITS 0
4$:	CLR	-(SP)			;WHAT GOOD SHOULD BE
	JSR	PC,CKDQES		;SAVE BD, AND REG # ON STACK
	CK11SC	<CKEDID!CKEPC!CKEGB>,<Bit not Clear>,<COULDN'T CLEAR BIT>
	.ASCIZ	\Bit not Clear\<377>
	.EVEN
5$:	ASR	R2			;ALL DONE?
	BNE	1$			;BRANCH BACK IF ANOTHER BIT TO TEST
	BR	CHKDQS		;GO CHECK SECONDARY REGS
;
CKDQES:	MOV	(SP)+,R1			;SAVE RETURN PC
	MOV	R0,-(SP)			;PUT C(ERR REG) ON STACK
	MOV	R2,-(SP)			;BIT WE TESTED
	BIS	#B15,(SP)		;INCLUDE ERROR BIT
	COM	(SP)			;
	BIC	(SP)+,(SP)		;KEEP ONLY THE INTERESTING BITS
	MOV	R4,-(SP)			;SAVE REG ADR
	ADD	#4,(SP)			;MAKE IT THE ERROR REG
	JMP	(R1)			;RETURN
;EDIT PAGE BREAK (FF)
; CHECK WE CAN LOAD VARIOUS DQ11 SECONDARY REGISTERS
;
CHKDQS:	CLR	R0			;1ST TRY TO CLEAR ALL SECONDARY REGISTERS
	JSR	PC,60$			;GO DO IT
	MOV	#-1,R0			;NOW TRY TO SET ALL SECONDARY REGISTERS
	JSR	PC,60$
	MOV	#1,R0			;BIT TO LOAD
10$:	JSR	PC,60$			;TRY TO LOAD BIT
	ASL	R0			;SHIFT BIT
	BNE	10$			;BRANCH IF STILL HAVE BITS TO TEST
	MOV	#RG.SYN,R1		;NOW TRY TO LOAD REG WITH REG #
12$:	MOV	R1,R0			;DATA = REGISTER NUMBER
	JSR	PC,CKDQSL		;TRY TO LOAD REGISTER
	CMP	#RG.SYN,R1
	BNE	14$
	DEC	R1			;SKIP REG 10
14$:	DEC	R1			;ON TO NEXT REGISTER
	BPL	12$
	MOV	#RG.SYN,R1		;NOW CHECK IT LOADED
16$:	MOV	R1,R0			;DATA SHOULD BE SAME
	JSR	PC,CKDQSR		;CHECK DATA STILL THERE
	CMP	#RG.SYN,R1		;WAS THIS THE FIRST REG ?
	BNE	18$
	DEC	R1			;YES SO SKIP REG 10
18$:	DEC	R1			;ON TO NEXT REGISTER
	BPL	16$			;DO REST IF ANY
	MOV	#RG.MSC,R1		;NOW TEST MISC REG
	CLR	R0			;TRY TO CLEAR REGISTER
	JSR	PC,CKDQSL		;TRY TO LOAD IT
	MOV	#2,R0			;TEST STEP-MODE BIT
	JSR	PC,CKDQSL
	MOV	#
10,R0			;TEST TEST-LOOP BIT
	JSR	PC,CKDQSL
	CLR	R0
	JSR	PC,CKDQSL		;CLEAR MISC REG
	BR	CHKDQL			;DO A LOOP BACK TEST
;
60$:	MOV	#RG.SYN,R1		;1ST REGISTER TO LOAD
62$:	JSR	PC,CKDQSL
	CMP	#RG.SYN,R1		;DID WE JUST CHECK THE SYN REG ?
	BNE	64$
	DEC	R1			;YES SO SKIP A REG
64$:	DEC	R1			;ON TO THE NEXT REG
	BPL	62$
	RTS	PC			;YES
;
; LOAD A DQ11 2NDARY REGISTER
; CALL	MOV	#DATA,R0
;	MOV	#REG,R1
;	JSR	PC,CKDQSL
CKDQSL:	BIS	#DQ.MBM,R1
	MOVB	R1,5(R4)		;SELECT THE REGISTER
	MOV	R0,6(R4)		;LOAD THE DATA
CKDQSR:	BIS	#DQ.MBM,R1
	MOVB	R1,5(R4)		;SELECT THE REGISTER
	BIC	#DQ.MBM,R1
	CMP	R0,6(R4)		;CHECK TO SEE IF WE LOADED IT
	BNE	10$
	RTS	PC
10$:	MOV	R0,-(SP)			;SAVE GOOD DATA
	MOV	6(R4),-(SP)		;SAVE BAD DATA
	MOV	R1,-(SP)			;SAVE 2ND REG #
	CK11SC	<CKEDID!CKEPC!CKEGB>,<Secondary Reg Err>,<SECONDARY REG ERROR>
	.ASCIZ	\Secondary Reg Err\<377>
	.EVEN
	RTS	PC			;RETURN
.PAGE
; DISCOVER WHAT THE SPECIAL CHARACTERS ARE IN THE DQ11.
;
CHKDQL:
	    .IF NE SPCVFY		;CHECK FOR SPECIAL CHARS ONLY IF USED
	CLR	CHKCHR+CKFLG		;CLEAR WHERE WE COUNT SPECIAL CHARS
	MOV	R2,-(SP)		;SAVE R2
	MOV	R3,-(SP)		;SAVE R3 (VECTOR)
	MOV	R5,-(SP)		;SAVE R5
	MOVB	#255,CHKXBF+2		;SOMETHING OTHER THAN SYNC (226)
	CLR	R3			;START WITH CHARACTER 0
CKDQLP:
1$:	JSR	PC,CKDQCL		;CLEAR DQ
	MOV	#CHKRBF,R5		;ADDRESS TO LOAD
	MOV	#<<CHKRBF-CHKXBF>/2>,R1	;LENGTH TO LOAD
	CLR	R2			;DATA TO LOAD
	JSR	PC,CKLDBF		;LOAD BUFFER
	MOV	#226*401,CHKXBF		;SYNC CHAR WE USE
	MOVB	R3,CHKXBF+3		;PUT CHAR IN XMIT BUFFER
	DQREGS	SYN,(R4)		;SYNC REG
	MOV	#226*401,6(R4)		;PUT SYNC CHAR IN REG
	DQREGS	MSC,(R4)		;MISC REG
	MOV	#4010,6(R4)		;LOAD MISC REG
	DQREGS	PTA,(R4)		;PRI XMIT ADDR REG
	MOV	#CHKXBF,6(R4)		;LOAD XMIT PRI ADDR REG
	DQREGS	STA,(R4)		;SEC XMIT ADR REG
	MOV	#CHKXBF,6(R4)		;LOAD XMIT SEC ADDR REG
	DQREGS	PRA,(R4)		;PRIMARY RECEIVE ADDR REG
	MOV	#CHKRBF,6(R4)		;LOAD REC ADDR REG PRI
	DQREGS	SRA,(R4)		;SEC REC ADR REG
	MOV	#CHKRBF,6(R4)		;LOAD REC ADDR REG SEC
	DQREGS	PTC,(R4)		;PRI XMIT CC
	MOV	#-4,6(R4)		;LOAD PRI XMIT CC
	DQREGS	STC,(R4)		;SEC XMIT CC
	MOV	#-2,6(R4)		;LOAD SEC XMIT CC
	DQREGS	PRC,(R4)		;PRI REC CC
	MOV	#-2,6(R4)		;LOAD PRI REC CC
	DQREGS	SRC,(R4)		;SEC REC CC
	MOV	#-2,6(R4)		;LOAD SEC REC CC
	CLR	R1			;CLEAR SAVED STATUS
	MOV	#DQ.RGO!DQ.CIE!DQ.RIE,(R4)	;TELL REC TO GO WITH IE
	MOV	#DQ.XGO,2(R4)		;TELL XMIT TO GO
CKDQWA:	CLR	R5			;FOR TIME-OUT
	CLR	R0			;UPON INT R0 WILL GET VECTOR
	CLR	PS			;LET INT HAPPEN
1$:	TST	R0			;SEE IF AN INTERRUPT
	BNE	2$			;BRANCH IF ONE (R0 IS NON 0)
	SOB	R5,1$			;TIME OUT
	CK11SC	<CKEPC!CKEDID>,<Timed Out>,<TIMED OUT WHILE WAITING FOR AN INT>
	.ASCIZ	\Timed Out\<377>
	.EVEN
	BR	CKDQOT		;DON'T CHK THIS DQ ANY MORE
2$:	CMP	R0,CHKCHR+CKDV		;SEE IF WE CAME TO THE RIGH VECTOR
	BEQ	CKDQGI			;BRANCH IF WE DID
	CKSERR	<CHKCHR+CKDV>,R0,R4	;SAVE GD,BD,DEV ADR
	CK11SC	<CKEPC!CKEDID!CKEGB>,<Interrupted to Wrong Vector>,<INTERRUPTED TO WRONG VECTOR>
	.ASCIZ	\Interrupted to Wrong Vector\<377>
	.EVEN
	BR	CKDQOT			;DON'T CHK ANY MORE OF THIS DQ
CKLDBF:	MOV	R2,(R5)+		;PUT DATA IN ADDR
	SOB	R1,CKLDBF		;FILLED?
	RTS	PC			;YES.
;
CKDQGI:	MOV	(R4),R5			;GET STATUS
	TSTB	R5			;SEE IF DONE YET?
	BMI	1$			;BRANCH IF SO
	BIT	#DQ.RDS,R5		;SEE IF SEC INT
	BNE	2$			;BRANCH IF IT IS
	BIT	#DQ.VCH,R5		;SEE IF SPECIAL CHAR INT
	BNE	3$			;BRANCH IF SO
	CK11SC	<CKEDID!CKEPC>,<Illegal Interrupt>,<SOME BIT OTHER THAN SPEC CHAR INT'ED US>
	.ASCIZ	\Illegal Interrupt\<377>
	.EVEN
	BR	CKDQOT			;DON'T CHECK ANY MORE OF THIS DQ
1$:	BIT	#DQ.VCH,R5		;SEE IF SPECIAL CHAR INT
	BEQ	5$			;BRANCH IF NOT
	MOV	R5,R1			;SAVE REC STATUS FOR PRINT
	BIC	#DQ.VCH!DQ.RDP!DQ.CIE,(R4)	;DISMISS INT
	BR	CKDQWA			;GO WAIT FOR ANOTHER INT
3$:	BIC	#DQ.VCH,(R4)		;CLEAR FOR EXIT
	BR	CKDQWA			;GO WAIT FOR ANOTHER INT
5$:	BIC	#DQ.RDP,(R4)		;
	BR	CKDQWA			;GO WAIT FOR ANOTHER INT
2$:	BIT	#DQ.VCH,R1		;WAS IT A SPECIAL CHAR?
	BEQ	6$			;NO, SO JUST UPDATE PATTERN
	BIT	#DQ.CHR,R1		;WAS THERE CAUSE FOR VCH ?
	BNE	9$			;MUST BE NON 0 OR WHY ARE WE HERE
	CK11SC	<CKEDID!CKEPC>,<Spec Char Code Fld 0>,<SPECIAL CHAR CODE FIELD 0>
	.ASCIZ	\Spec Char Code Fld 0\
	.EVEN
	BR	CKDQOT			;DON'T CHECK ANY MORE OF THIS DQ
9$:	BIT	#DQ.ETB!DQ.ETX!DQ.ENQ,R1 ;WAS IT INTERESTING SPECIAL CHAR ?
	BNE	10$			;IF SO FIND WHICH
	BIS	#B15,CHKCHR+CKFLG	;SET FLAG THAT SYNC INTERRUPTS
	BR	6$
69$:	.WORD	B10
	.WORD	B9
	.WORD	B8
10$:	MOV	#4,R5			;INDEX FOR SPECIAL CHAR TABLE
	INC	CHKCHR+CKFLG		;COUNT SPECIAL CHARACTER
12$:	BIT	69$(R5),R1		;CHECK FOR SPECIAL CHAR FLAG
	BEQ	14$
	MOV	R3,CHKCHR+CKSPC(R5)	;PUT INTO THE TABLE
14$:	SUB	#2,R5
	BGE	12$			;LOOK FOR ANOTHER MAYBE
6$:	INCB	R3			;NEXT CHAR TO CHECK
	BEQ	4$			;BRANCH IF ALL DONE
	BIC	#DQ.RDS!DQ.VCH!DQ.CIE!DQ.RIE,(R4)	;
	JMP	CKDQLP			;
CKDQOT=.
4$:	MOV	(SP)+,R5
	MOV	(SP)+,R3
	MOV	(SP)+,R2
	CMPB	CHKCHR+CKFLG,#4		;SHOULD BE NO MORE THAT 4
	BLE	15$			;CHECK IF SO
	CK11SC	<CKEDID!CKEPC>,<More than 4 Spec Char Det>,<MORE THAN 4 SPEC CHAR WERE DETECTED>
	.ASCIZ	\More than 4 Spec Char Det\
	.EVEN
	BR	CKDQOT			;DON'T CHECK ANY MORE OF THIS DQ
	    .IFF
10$:	JSR	R0,CKTSTR
	.ASCIZ	\	SKIPPING SPEC CHAR TEST\
	.EVEN
	MOV	#377+<<.+6-10$>/2>,10$	;SHUT OFF SKIPPING COMMENT
	    .ENDC ; .IF NE SPCVFY
15$:	RTS	PC			;RETURN
.PAGE
;ROUTINE TO CLEAR THE ENTIRE DQ
;
CKDQCL:	MOV	R0,-(SP)
	MOV	R1,-(SP)
	MOV	R2,-(SP)
	DQREGS	MSC,(R4)		;SELECT MISC REG
	MOV	#DQ.MC,6(R4)		;MASTER CLEAR
	DQREGS	MSC,(R4)		;SELECT MISC REG AGAIN
	MOV	#DQ.MC,6(R4)		;MASTER CLEAR AGAIN
	MOV	#17,R0			;CLEAR ALL SEC REG
	MOV	#B12,R2			;CLEAR BITS 13+14 IN ERR
1$:	MOV	R2,4(R4)		;SELECT A SEC REG
	CLR	6(R4)			;CLEAR THAT SEC REG
	ADD	#B8,R2			;SELECT NEXT SEC REG TO CLEAR
	SOB	R0,1$			;ALL SEC CLEARED?
	MOV	(SP)+,R2		;RESTORE REGS USED
	MOV	(SP)+,R1
	MOV	(SP)+,R0
	RTS	PC			;RETURN
;
.IIF NDF CHKBSZ,CHKBSZ=10
CHKXBF:	.BLKB	CHKBSZ
CHKRBF:	.BLKB	CHKBSZ
;
	    .ENDC	;RANGES OVER ENTIRE DQ CHECK (NDF FT.D75)
;
.IIF	DF,FT.D75,	RTS	PC
	    .ENDC ;NE FTDQ11
;EDIT PAGE BREAK (FF)
.SBTTL		CHECK DS11 HDW
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,CKDS11
;
	    .IIF NDF FTDS11,FTDS11=0
	    .IF NE FTDS11
CKDS11:
	MOV	DS.AUX,R1		;GET AUX REG TO SEE HOW MANY GROUPS
	MOV	#DS.AD1,R2		;FOR CHECKING GROUP NUMBER
	MOV	#4,R0			;ALWAYS 1 GROUP IF DS11
1$:	BIT	R2,R1			;GROUP EXIST?
	BEQ	2$			;BRANCH IF NO GROUP
	ADD	#4,R0			;COUNT 4 LINES FOR EACH GROUP
	ASL	R2			;POSITION TO CHECK NEXT GROUP BIT
	BNE	1$			;BRANCH IF WE CAN CHECK ANOTHER
2$:	JSR	PC,CKTBOC		;PRINT NUMBER OF LINES
	CK11SC	CKENCL,< Lines>
	.ASCIZ	\ Lines\
	.EVEN
	MOV	#DS.AUX,R1		;CHECK THE AUX REG
	JSR	R5,CHKBIT		;CHECK FOLLOWING BITS
	1700				;BITS TO CHECK
	MOV	#DS.DVA-2,R1		;SET TO CHECK LINES
	MOV	#DS.VEC,CHKCHR+CKDV	;VECTOR TO START AT
	MOV	26(R5),CHKCHR+CKPI	;PI LEVEL FOR ALL DS11
	MOV	R0,R2			;NUMBER OF LINES TO CHECK
	MOV	#CHKCHR,R0		;POINT TO BLOCK FOR MAIN CALL
3$:	ADD	#2,R1			;LINE ADR TO CHECK
	MOV	R1,CHKCHR+CKDA		;MAIN NEEDS THIS INFO
	JSR	R5,CHKBIT		;CHK RECEIVE STATUS REG
	6477				;BITS TO CHECK
	TST	(R1)+			;ADVANCE TO REC DATA REG
	JSR	R5,CHKBIT		;CHK RECEIVE DATA REG
	7777				;BITS TO CHECK
	TST	(R1)+			;ADVANCE TO XMIT STATUS REG
	JSR	R5,CHKBIT		;CHK XMIT STATUS REG
	476				;BITS TO CHECK
	TST	(R1)+			;ADVNACE TO XMIT DATA REG
	JSR	R5,CHKBIT		;CHK XMIT DATA REG
	7777				;BITS TO CHECK
	JSR	PC,@14(R5)		;CALL THE MAIN PROGRAM
	ADD	#20,CHKCHR+CKDV		;ADVANCE VECTOR ADR FOR NEXT LINE
	ADD	#10,CHKCHR+CKDA		;ADVANCE DEVICE ADR FOR NEXT LINE
	SOB	R2,3$			;ALL LINES CHECKED?
	MOV	#DS.VEC,CHKCHR+CKDV	;SO "CHKDEV" WILL FILL OUT BLOCK
					;
	RTS	PC			;FINI CHECKING DS11
	    .ENDC ;NE FTDS11
.PAGE
.SBTTL		CHECK DTE20 HARDWARE
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,XDTE211
;
	    .IIF NDF FTDTE,FTDTE=0
	    .IF NE FTDTE
XDTE211:				;
	MOV	R1,R0		;FROM THE DEVICE ADDRESS
	ASR	R0		;BITS 5 AND 6 GIVE US WHICH ONE IT IS
	ASR	R0		;POSITION TO BITS 2 AND 3 WHICH IS
	ASR	R0		;WHERE THE VECTOR VARIES
	BIC	#^C14,R0	;ISOLATE THEM
	SUB	R0,CHKCHR+CKDV	;CORRECT OUR VECTOR ADDRESS
	JSR	R5,CHKBIT	;CHECK DLYCNT IN DTE'S RAM
	177777			; SINCE WE CAN ACCESS ALL THE BITS
	ADD	#CSTAT-DLYCNT,R1 ;POINT TO STATUS REGISTER
	MOV	#INTRON,(R1)	;ENABLE INTERRUPTS
	BIT	#INTSON,(R1)	;DOES DTE AGREE?
	BNE	10$		;YEP
	CK11SC	<CKEPC!CKEDID>,<Setting INTRON didn't set INTSON>
	.ASCIZ	\Setting INTRON didn't set INTSON\<377>
	.EVEN
10$:	MOV	#INT11S,(R1)	;NOW SEE IF IT WILL INTERRUPT US
	JSR	R5,CHKINL
	-1			;TIME DELAY COUNT
	MOV	#INTROF,(R1)	;TRY TO MAKE IT GO AWAY
	BIT	#INTSON,(R1)	;WHICH SHOULD TURN THIS OFF
	BEQ	20$		;OKAY
	CK11SC	<CKEPC!CKEDID>,<Setting INTROF didn't clear INTSON>
	.ASCIZ	\Setting INTROF didn't clear INTSON\<377>
	.EVEN
20$:	BIT	#RM,(R1)		;WE SHOULD BE RESTRICTED
	BNE	30$		;WE ARE, FINE
	CK11SC	<CKEPC!CKEDID>,<DTE20 is not restricted>
	.ASCIZ	\DTE20 is not restricted\<377>
	.EVEN			;
30$:	MOV	#DRESET,-(R1)	;REALLY INITIALIZE DTE20
	RTS	PC
	    .ENDC ;NE FT.DTE
.PAGE
.SBTTL		CHECK DU11 HDW
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,XDU11
	    .IIF NDF FTDU11,FTDU11=0
	    .IF NE FTDU11
XDU11:				;
	RTS	PC
	    .ENDC ;NE FTDU11
.PAGE
.SBTTL		CHECK DUP11 HDW
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,XUP11
	    .IIF NDF FTDUP1,FTDUP1=0
	    .IF NE FTDUP1
XDUP11:				;
	FIELD	$$,DUPRIE,DUPDTR ;
	JSR	R5,CHKBIT	;TEST THE RECVR CSR
	.WORD	DUPSSY!$$	;
	TST	(R1)+		;UP TO RECVR, BUT IT'S READ ONLY
	TST	(R1)+		;UP TO XMIT CSR
	JSR	R5,CHKBIT	;
	.WORD	DUPTMC!DUPTM1!DUPTM0!DUPTMI!DUPTIE!DUPTSN!DUPTHD
	TST	(R1)+		;UP TO XMIT DBR
	JSR	R5,CHKBIT	;
	.WORD	DUPXAB!DUPXEM!DUPXSM!DUPXDB
	MOV	R4,R1		;RESTORE DEVICE ADDRESS
				;(ADD INTERRUPT CHECK)
	RTS	PC		;
	    .ENDC ;NE FTDUP1
.PAGE
.SBTTL		CHECK DZ11 HDW
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,XDZ11
	    .IIF NDF FTDZ11,FTDZ11=0
	    .IF NE FTDZ11
XDZ11:				;
	JSR	R5,CHKBIT	;
	.WORD	DZ.TIE!DZ.RIE!DZ.SCN
	TST	(R1)+		;
	JSR	R5,CHKBIT	;
	.WORD	0		;
	MOV	R4,R1		;
				;ADD INTERRUPT TEST
	RTS	PC		;
	    .ENDC ;NE FTDZ11
;EDIT PAGE BREAK (FF)
.SBTTL		CHECK KG11 HARDWARE
;
XKG11:	SAVE	R3		;
	CHKCHR	R4,<#0>,<#0>	;
	CLR	R0		;
11$:	KGLOAD	R0		;
	CMP	R0,KGBCC(R4)	;CHECK THAT IT LOADED
	BEQ	12$		;OK
	CKSERR	R0,KGBCC(R4),R4	;GD,BD,ADR
	CK11SC	<CKEPC!CKEDID!CKEGB>,<Can't load BCC Correctly>,<BCC ERROR>
	.ASCIZ	\Can't load BCC Correctly\<377>
	.EVEN			;
12$:	SOB	R0,11$		;
				;
				; CHECK CRC PORTION
				;
	MOV	#777,R0		;FIRST ENTRY FOR CRC
	KGLOAD	#0		;CLEAR KG11
	CLR	R3		;CLEAR SOFTWARE COPY
20$:	JSR	PC,70$		;CALCULATE SOFTWARE BCC
	MOVB	R0,KGDATA(R4)	;INCLUDE CHAR IN HDW BCC
	CMP	R3,KGBCC(R4)	;
	BEQ	54$		;
	CKSERR	R3,KGBCC(R4),R4	;
	CK11SC	<CKEPC!CKEGB!CKEDID>,<Incorrect CRC>,<INCORRECT CRC>
	.ASCIZ	\Incorrect CRC\<377>
	.EVEN			;
54$:	SOB	R0,20$		;
				;
	RESTORE	R3		;
	RTS	PC		;
;
;SUBROUTINE TO CALCULATE CRC IN R3
;
70$:	SAVE	<R0,R1>		;
	BIC	#^C377,R0	;STRIP EXTRA BITS
	MOV	#8.,R1		;COUNTER
	XOR	R0,R3		;
	MOV	#120001,R0	;
72$:	CLC			;CLEAR CARRY BIT
	ROR	R3		;
	BCC	74$		;
	XOR	R0,R3		;
74$:	SOB	R1,72$		;
	RESTORE	<R1,R0>		;
	RTS	PC		;
.PAGE
.SBTTL		CHECK KMC/DMC HARDWARE
;
;CALL	MOV	#<VECTOR ADR OF KMC11>,R3
;	MOV	#<HDW ADR OF KMC11>,R4
;	MOV	#<HDW ADR OF KMC11>,R1
;	JSR	PC,XKMC11
;
	    .IIF NDF FTKMC,FTKMC=0
	    .IIF NDF FTDMC,FTDMC=0
	    .IF NE FTDMC
XDMC11:
XKMC11:	MOV	R5,-(SP)	;SAVE R5
	MOV	R4,-(SP)	; AND R4
	MOV	R3,-(SP)	; AND R3
	MOV	#MD.CLR,(R4)	;INITIALIZE THE KMC11
	MOV	MDCSRP,-(SP)	;LOG IN THE DEVICE
	BNE	10$		;NOT THE FIRST
	MOV	#MDCSR,(SP)	;THE FIRST, SET POINTER
	MOV	(SP),MDCSRP	;
10$:	MOV	R4,@(SP)+	;ENTER DEVICE CSR INTO STARTUP TABLE
	ADD	#2,MDCSRP	;UPDATE TABLE POINTER
	CLR	(R4)+		;CLEAR THE CSRS
	CLR	(R4)+		;
	CLR	(R4)+		;
	CLR	(R4)+		;
	MOV	R1,R4		;
	JSR	R5,CHKBIT	;VERIFY THESE BITS WORK
	.WORD	377		;ALL BITS OF BSEL 0
	TST	(R1)+		;LOOK AT SEL 2
	JSR	R5,CHKBIT	;VERIFY THESE BITS WORK
	.WORD	ALLBTS		;ALL BITS OF SEL 2
	TST	(R1)+		;LOOK AT SEL 4
	JSR	R5,CHKBIT	;VERIFY THESE BITS WORK
	.WORD	ALLBTS		;ALL BITS OF SEL 4
	TST	(R1)+		;LOOK AT SEL 6
	JSR	R5,CHKBIT	;VERIFY THESE BITS WORK
	.WORD	ALLBTS		;ALL BITS OF SEL 6
	    .IF NE FTKMCL
	TST	MDCODB+2	;IF WE ARE RETAINING THE CRAM...
	BEQ	20$		; DON'T CHECK INTERRUPTS (CLOBBERS CRAM 0)
	    .ENDC ;NE FTKMCL
				;CREATE A DMC INTERRUPT BY SETTING
				;  BUS RQ IN MP MISC BY JAMMING MP INSTRS
	MOV	#BR7,PS		;STOP INTERRUPTS
	MOV	#MD.RMI,(R4)	;SET ROM I ("JAM INSTRUCTION")
	MOV	#600,6(R4)	;600 = "MOVE #200,BRG"
	BIS	#MD.SMP,(R4)	;EXECUTE THE INSTRUCTION
	CLR	(R4)		;TURN OFF STEP AND ROM I
	MOV	#MD.RMI,(R4)	;SET ROM I AGAIN
	MOV	#61231,6(R4)	;61231 = "MOVE BRG,MISC" (SETS BUS RQ)
	BIS	#MD.SMP,(R4)	;EXECUTE
	CLR	(R4)		;TURN OFF ROM I
	JSR	R5,CHKINL	;CHECK FOR THE RESULTING INTERRUPT
	.WORD	177777		;
	MOV	#MD.CLR,(R4)	;CLEAR INTERFACE
.PAGE
; IF WE HAVE A VALID COPY OF THE MICROCODE, WE CAN TEST
;  THE CRAM.  OTHERWISE BYPASS MOST OF THE TESTING.
;
20$:
	    .IF NE FTKMC
	MOV	#12,R1		;CHECK ARBITRARY LOCATION IN CRAM
	JSR	PC,CKMDRD	;READ FROM IT
	MOV	R0,-(SP)	;SAVE DATA READ
	COM	R0		;INVERT IT
	JSR	PC,CKMDWR	;WRITE BACK INVERTED DATA
	JSR	PC,CKMDRD	;READ IT BACK OUT
	CMP	R0,(SP)+	;CHECK IT AGAINST WHAT WAS WRITTEN
	BNE	22$		;DATA DIFFERENT, CRAM IS READ/WRITE
				;NOT WRITTEN, CRAM IS A CROM
	CMP	CKDNAM,#N.KMC11	;DID YOU EXPECT A KMC?
	BNE	21$		;NO, SKIP CRAM CHECK, NO MSG
	MOV	CHKFLG,-(SP)	;PREVENT ERROR FROM BEING SET
	CK11SC	CKEDID,<DEV IS DMC>
	.ASCIZ	"	CRAM is not R/W, device is a DMC"
	.EVEN			;
	MOV	(SP)+,CHKFLG	;RESTORE PREVIOUS FLAG WORD
21$:	JMP	CKMDXT		;SKIP CRAM CHECK
				;
22$:	COM	R0		;INVERT DATA BACK
	JSR	PC,CKMDWR	;REWRITE AGAIN
	CMP	CKDNAM,#N.DMC11	;WAS A DMC EXPECTED?
	BNE	23$		;NO, MUST HAVE BEEN A KMC CALL
	MOV	CHKFLG,-(SP)	;PREVENT ERROR FROM BEING SET
	CK11SC	CKEDID,<dev is a KMC>
	.ASCIZ	"	R/W CRAM present, device is a KMC"
	.EVEN			;
	MOV	(SP)+,CHKFLG	;RESTORE PREVIOUS FLAG WORD
23$:	    .IF NE FTKMCL
	TST	MDCODB+2	;IS MICROCODE IMAGE INVALID?
	BNE	24$		;NOT OBVIOUSLY
	JSR	PC,CKMDEX	;YES, BE SURE WE CAN CYCLE THE CRAM
	JMP	CKMDXT		; BUT LEAVE ITS CONTENTS ALONE.
24$:
	    .ENDC ;NE FTKMCL
	CLR	R1		;START AT CRAM ADDRESS 0
30$:	CLR	R0		;DATA IS ZERO
	JSR	PC,CKMDCK	;WRITE 0 AND CHECK IT
	INC	R1		;NEXT CRAM LOCATION
	CMP	#2000,R1	;REACHED THE END OF THE CRAM?
	BNE	30$		;NO, DO THE REST.
	JSR	PC,CKMDEX	;COMPLEMENT THE CRAM TWICE
	CLR	R1		;START AT THE BEGINNING AGAIN
36$:	JSR	PC,CKMDRD	;READ A WORD FROM THE CRAM
	TST	R0		;IS IT ZERO?
	BEQ	42$		;YES, THAT IS OK.
	CKSERR	<#0>,R0,R1	;GOOD, BAD, CRAM ADDRESS
	CK11SC	<CKEPC!CKEGB!CKEDID>,<CRAM CLEAR FAILED>,<CRAM CLEAR FAILED>
	.ASCIZ	/ CRAM clear failed /
	.EVEN
42$:	INC	R1		;NEXT CRAM ADDRESS
	CMP	#2000,R1	;REACHED THE END OF THE CRAM?
	BNE	36$		;NO, DO THE REST
;
; NOW SET EACH CRAM LOCATION TO ITS OWN ADDRESS.  THIS CHECKS FOR
;  ADDRESSING FAILURES.
;
	CLR	R1		;START AT LOCATION ZERO
50$:	MOV	R1,R0		;GET ADDRESS
	ASL	R0		; * 2 (WE ARE PUTTING THE 10-BIT
	ASL	R0		; * 4  CRAM ADDRESS IN THE MIDDLE
	ASL	R0		; * 8  OF THE 16-BIT WORD.)
	JSR	PC,CKMDCK	;WRITE ADDRESS INTO CRAM
	INC	R1		;NEXT CRAM ADDRESS
	CMP	R1,#2000	;REACHED END OF CRAM YET?
	BLO	50$		;NO, GO DO THE REST.
	JSR	PC,CKMDEX	;COMPLEMENT THE CRAM TWICE
	CLR	R1		;START AT BEGINNING OF CRAM AGAIN
55$:	JSR	PC,CKMDRD	;READ WORD FROM CRAM
	MOV	R1,R2		;GET CRAM ADDRESS
	ASL	R2		; * 2
	ASL	R2		; * 4
	ASL	R2		; * 8
	CMP	R0,R2		;IS THE CRAM OK?
	BEQ	60$		;YES
	CKSERR	R2,R0,R1	;NO, STUFF GOOD, BAD, AND CRAM ADDRESS
	CK11SC	<CKEPC!CKEGB!CKEDID>,<CRAM ERROR>,<CRAM ERROR>
	.ASCIZ	/ CRAM data = address error /
	.EVEN			;
60$:	INC	R1		;NEXT CRAM ADDRESS
	CMP	R1,#2000	;REACHED THE END OF THE CRAM?
	BLO	55$		;NO, GO DO THE REST
;
; NOW LOAD THE APPLICATION CODE INTO THE CRAM, IF REQUESTED.
;
	    .IF NE FTKMCL
	CLR	R1		;START AT THE BEGINNING OF THE CRAM
	MOV	#MDCODB,R2	;POINT TO APPLICATION CODE
70$:	MOV	(R2)+,R0	;GET WORD TO LOAD
	JSR	PC,CKMDCK	;WRITE IT INTO THE CRAM
	INC	R1		;POINT TO NEXT CRAM LOCATION
	CMP	R2,#MDCODE	;REACHED END OF PROGRAM?
	BNE	70$		;NO, LOAD THE REST
	JSR	PC,CKMDEX	;COMPLEMENT THE CRAM TWICE
	CLR	R1		;START AT BEGINNING OF CRAM AGAIN
	MOV	#MDCODB,R2	;POINT TO APPLICATION CODE AGAIN
72$:	JSR	PC,CKMDRD	;READ A WORD FROM THE CRAM
	MOV	(R2)+,R3	;GET WORD THAT SHOULD BE THERE
	CMP	R3,R0		;IS IT RIGHT?
	BEQ	78$		;YES
	CKSERR	R3,R0,R1	;GOOD, BAD, CRAM ADDRESS
	CK11SC	<CKEPC!CKEGB!CKEDID>,<CRAM LOAD ERROR>,<CRAM LOAD ERROR>
	.ASCIZ	/ CRAM load error /
	.EVEN			;
78$:	INC	R1		;NEXT CRAM ADDRESS
	CMP	R2,#MDCODE	;REACHED END OF APPLICATION PROGRAM?
	BLO	72$		;NO, DO THE REST
	    .ENDC ;NE FTKMCL
	    .ENDC ;NE FTKMC
;
; DMC (KMC) CHECK COMPLETED
;
CKMDXT:	MOV	#MD.CLR,(R4)	;BE SURE THE KMC11 IS CLEAR
	MOV	(SP)+,R3	;RESTORE R3
	MOV	(SP)+,R4	; AND R4
	MOV	(SP)+,R5	; AND R5
	RTS	PC		;RETURN.
.PAGE
	    .IF NE FTKMC	;THESE SUBROUTINES APPLY ONLY TO
				;  WRITEABLE CONTROL STORES, I.E., KMC'S
;
; SUBROUTINE TO COMPLEMENT THE DATA IN THE KMC11'S CRAM.
;  ENTERING AT CKMDEX WILL CAUSE THE ROUTINE TO EXECUTE TWICE -
;  IF THE KMC11 IS WORKING PROPERLY THIS WILL LEAVE THE CRAM UNCHANGED.
;
CKMDEX:	JSR	PC,(PC)		;CALL REST OF ROUTINE ONCE, RETURN
				;  HERE AND FALL INTO IT FOR SECOND PASS
	CLR	R1		;START AT BEGINNING OF CRAM
80$:	JSR	PC,CKMDRD	;READ WORD FROM CRAM
	COM	R0		;COMPLEMENT IT
	JSR	PC,CKMDCK	;WRITE IT BACK (AND CHECK IT)
	INC	R1		;NEXT CRAM LOCATION
	CMP	R1,#2000	;REACHED END OF CRAM?
	BLO	80$		;NO, DO THE REST
	RTS	PC		;YES, ALL DONE
.PAGE
; SUBROUTINE TO WRITE A WORD INTO THE KMC11'S CRAM
;
; R0 = WORD TO WRITE
; R1 = CRAM ADDRESS
; R4 = POINTER TO KMC11 CSR
;
CKMDWR:	CLR	(R4)		;CLEAR BSEL 1
	MOV	R1,4(R4)	;SET ADDRESS INTO SEL 4
	MOV	R0,6(R4)	;LOAD DATA INTO SEL 6
	BIS	#MD.RMO,(R4)	;SET ROM O
	BIS	#MD.RMO!MD.CWR,(R4) ;SET CRAM WRITE ALSO
	CLR	(R4)		;CLEAR ROM O AND CRAM WRITE
	RTS	PC		;RETURN
;
; SUBROUTINE TO WRITE AND VERIFY A WORD IN THE CRAM
;
; CALLED AS CKMDWR
;
CKMDCK:	MOV	R0,-(SP)	;SAVE DATA TO BE WRITTEN
	JSR	PC,CKMDWR	;WRITE THE WORD
	JSR	PC,CKMDRD	;READ IT BACK
	CMP	R0,(SP)		;DATA SAME AS WRITTEN?
	BEQ	85$		;YES.
	MOV	R2,-(SP)	;NO, SAVE R2
	MOV	2(SP),R2	;GET BAD DATA FROM CRAM
	CKSERR	R2,R0,R1	;GOOD, BAD, CRAM ADDRESS
	CK11SC	<CKEPC!CKEGB!CKEDID>,<CRAM DATA ERROR>,<CRAM DATA ERROR>
	.ASCIZ	/ CRAM data error in write check /
	.EVEN
	MOV	(SP)+,R2	;RESTORE R2
85$:	MOV	(SP)+,R0	;RESTORE DATA
	RTS	PC		;RETURN
;
; SUBROUTINE TO READ A WORD FROM THE KMC11'S CRAM.
;
; R1 = ADDRESS
; R4 = POINTER TO KMC11 CSR
;
; ON RETURN:
;
;  R0 = DATA FROM CRAM
;
CKMDRD:	CLR	(R4)		;CLEAR BSEL 1
	MOV	R1,4(R4)	;SET ADDRESS INTO BSEL 4
	BIS	#MD.RMO,(R4)	;SET ROM O
	MOV	6(R4),R0	;FETCH DATA
	CLR	(R4)		;CLEAR ROM O
	RTS	PC		;RETURN
	    .ENDC ;NE FTKMC
	    .ENDC ;NE FTDMC
;EDIT PAGE BREAK (FF)
.SBTTL		CHECK LP11 HARDWARE
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,XLE11
;
	    .IIF NDF FTLE11,FTLE11=0
	    .IF NE FTLE11
XLE11:				;
	BIT	#LE.ERR,(R4)	;SEE IF DEV READY
	BEQ	1$		;BRANCH IF RDY
	CK11SC	<CKEDID!CKENCL>,< Not Rdy>
	.ASCIZ	\ Not Rdy\<377>
	.EVEN			;
1$:	JSR	R5,CHKBIT	;CHECK HDW BITS
	.WORD	LE.INE
	$CKINT	,R4,<LE.INE>,<LE.DNE>
	RTS	PC
	    .ENDC ;NE FTLE11
.PAGE
.SBTTL		CHECK LP20 HARDWARE
;
	    .IIF NDF FTLP20,FTLP20=0
	    .IF NE FTLP20
XLP11:				;
	MOV	#BR7,PS		;
	MOV	#LP.RSE!LP.LOI,(R4) ;CLEAR CONTROLLER
	ADD	#LPRAMD,R1	;POINT TO RAM DATA BUFFER
	MOV	R1,R2		;
	TST	(R2)+		;POINT TO CHAR BUFFER
	CLRB	(R2)		;SET RAM ADDRESS TO ZERO
10$:	CLR	(R1)		;CLEAR RAM LOCATION
	INCB	(R2)		;UP RAM ADDRESS
	BNE	10$		;  UNTIL IT OVERFLOWS
	MOV	R4,R1		;RECOVER BASE CRS ADDRESS
	CLR	LPBSAD(R1)	;SET UP HARMLESS TRANSFER
	MOV	#-1,LPBCTR(R1)	;
	JSR	R5,CHKBIT	;CHECK R/W ON CSRA
	.WORD	LP.DH!LP.IE!LP.XAD!LP.MDS!LP.PEN
				;
	TST	(R1)+		;UP TO CSRB
	JSR	R5,CHKBIT	;
	.WORD	LP.TS2!LP.TS1!LP.TS0
	MOV	#LP.RSE!LP.LOI,(R4) ;
				;
	TST	(R1)+		;CHECK R/W ON BUS ADDRESS
	JSR	R5,CHKBIT	;
	.WORD	ALLBTS		;
	MOV	#LP.RSE!LP.LOI,(R4) ;
				;
	MOV	#3,R2		;NEXT THREE REGISTERS ARE ALIKE
20$:	TST	(R1)+		;BYTE COUNT, PAGE CONT, RAMDATA
	JSR	R5,CHKBIT	;
	.WORD	7777		;
	MOV	#LP.RSE!LP.LOI,(R4) ;
	SOB	R2,20$		;
				;
	TST	(R1)+		;CHECK R/W ON CHAR BUFFER
	JSR	R5,CHKBIT	;
	.WORD	ALLBTS		;
	MOV	#LP.RSE!LP.LOI,(R4) ;
				;
	MOV	R4,R1		;RECOVER BASE CSR ADDRESS
	BIT	#LP.ONL,(R1)	;PRINTER AVAILABLE?
	BNE	30$		;YES
	CK11SC	0,<NOT READY>
	.ASCIZ	"LP20 not ready"
	.EVEN			;
	RTS	PC		;
				;
30$:	MOV	#-1,LPBCTR(R1)	;SET CHAR COUNT
	MOV	R1,LPBSAD(R1)	;SET ADDRESS TO SELF
	ADD	#LPCBUF,LPBSAD(R1) ;
	MOV	#LP.B17!LP.B16!LP.GO,(R1) ;SET HIGH ADDRESS BITS AND START
	$CKINT	,R4,LP.IE,LP.IE	;
	RTS	PC		;
	    .ENDC ;NE FTLP20
.PAGE
.SBTTL		CHECK MD11 HDW
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,XMD11
	    .IIF NDF FTMD11,FTMD11=0
	    .IF NE FTMD11
XMD11:				;
	RTS	PC
	    .ENDC ;NE FTMD11
.PAGE
.SBTTL		DUMMY NULL DEVICE CHECKER
;
;
;
XNL11:	RTS	PC	;DUMMY
.PAGE
.SBTTL		CHECK PA611P HARDWARE
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,XP611
;
	    .IIF NDF FTP611,FTP611=0
	    .IF NE FTP611
XP611:				;
	RTS	PC
	    .ENDC ;NE FTP611
.PAGE
.SBTTL		CHECK PA611R HARDWARE
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,XR611
;
	    .IIF NDF FTR611,FTR611=0
	    .IF NE FTR611
XR611:				;
	RTS	PC
	    .ENDC ;NE FTR611
.PAGE
.SBTTL		CHECK PP11 HARDWARE
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,XPP11
;
	    .IIF NDF FTPP11,FTPP11=0
	    .IF NE FTPP11
XPP11:
	JSR	R5,CHKBIT
	PP.INE
	$CKINT	,R4,<PP.INE>,<PP.RDY>
	RTS	PC
	    .ENDC ;NE FTPP11
.PAGE
.SBTTL		CHECK PR11 HARDWARE
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,XPR11
;
	    .IIF NDF FTPR11,FTPR11=0
	    .IF NE FTPR11
XPR11:					;
	JSR	R5,CHKBIT		;CHECK HARDWARE BITS
	PR.INE
	CLR	R0			;FOR TIME OUT
	BIS	#PR..RE!PR.INE,(R4)	;TELL READER TO DO SOMETHING
					; TO FORCE ANY INTERRUPT COND
1$:	BIT	#PR.DNE!PR.ERR,(R4)	;SEE IF AN INT CONDITION IS THERE
	BNE	2$			;IF NOT, THEN WAIT FOR ONE.
	SOB	R0,1$			;TIME OUT TO CATCH NO RESPONSE
	CK11SC	<CKEDID!CKEPC>,<Timed Out>,<NO RESPONSE>
	.ASCIZ	\Timed Out\<377>
	.EVEN
	BIC	#PR.INE,(R4)		;DISABLE INT ENABLE
	RTS	PC			;EXIT
2$:	JSR	R5,CHKINL		;FIND INT LEVEL
	-1				;FOR TIME-OUT
	BIC	#PR.INE,(R4)		;DISABLE INTS
	RTS	PC
	    .ENDC ;NE FTPR11
.PAGE
.SBTTL		CHECK RH11 HARDWARE
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,XRH11
;
	    .IIF NDF FTRH11,FTRH11=0
	    .IF NE FTRH11
XRH11:	BIS	#1,CHKRP+4+0	;GROSS KLUDGE TO PREVENT CHKDEV FROM
	RTS	PC		; FINDING WHAT LOOKS LIKE AN RP.
				; (THE DEVICE REGISTERS OVERLAP)
	    .ENDC ;NE FTRH11
.PAGE
.SBTTL		CHECK TC11 HARDWARE
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,XTC11
;
	    .IIF NDF FTTC11,FTTC11=0
	    .IF NE FTTC11
XTC11:				;
	    .IF NDF,FT.D75
	JSR	R5,CHKBIT	;TEST FOLLOWING BITS
	TC.D17!TC.D16
	TST	(R1)+		;ADVANCE TO COMMAND REGISTER
	JSR	R5,CHKBIT		;TEST FOLLOWING BITS
	TC..MM!TC..DI!TC.REV!TC.US7!TC.INE!TC.A17!TC.A16
	TST	(R1)+		;ADVANCE TO WORD COUNT REG
	JSR	R5,CHKBIT	;TEST FOLLOWING BITS
	-1
	TST	(R1)+		;ADVANCE TO BUS ADDR REG
	JSR	R5,CHKBIT		;TEST THE FOLLOWING BITS
	-1
	TST	(R1)+		;ADVANCE TO DATA REGISTER
	JSR	R5,CHKBIT	;CHECK FOLLOWING BITS
	-1
	MOV	R4,R1		;SET UP ADR FOR INT CHK
	TST	(R1)+		;ADVANCE TO COMMAND REG
	MOV	R1,R2		;SET UP FOR INT CHK
	$CKINT	,,<TC.INE>,<TC.RDY>
	    .ENDC ;IF NDF FT.D75
	RTS	PC
	    .ENDC ;NE FTTC11
.PAGE
.SBTTL		CHECK TM11 HARDWARE
;
;CALL	MOV	#<VECTOR ADR>,R3
;	MOV	#<HDW ADR>,R4
;	MOV	#<HDW ADR>,R1
;	JSR	PC,XTM11
;
	    .IIF NDF FTTM11,FTTM11=0
	    .IF NE FTTM11
XTM11:				;
	RTS	PC
	    .ENDC ;NE FTTM11
.PAGE
.SBTTL		NULL DIAGNOSTIC
;
;
;
X.....:				;
	JSR	R0,CKTSTR	;
	.ASCIZ	"; integrity not tested"
	.EVEN			;
	MOV	#177776,CKDEVN	;SET COUNT TO PREVENT MORE TYPEOUTS
	RTS	PC		;
;EDIT PAGE BREAK (FF)
.SBTTL	TTY SUPPORT FOR TYPE OUTS
;
CKTRPT:	.WORD	0		;REPORT DESTINATION DEVICE
				; B15 - CTY
				; B7 - REMOTE DEVICE
;
; TYPE THE MESSAGE STRING POINTED TO BY R0
;
; CALL	JSR	PC,CKTTXT	;R0 CONTAINS ADDR OF TXT
; ON EXIT R0 POINTS TO THE EVEN LOCATION FOLLOWING THE TEXT
;
	    .ENABL LSB
CKTTXT:	SAVE	<R1>
10$:	MOVB	(R0)+,R1	;GET THE NEXT CHARACTER
	BEQ	20$		;BRANCH IF END (NULL)
	JSR	PC,CKTCHR	;TYPE CHAR
	BR	10$		;GET NEXT CHAR
				;
20$:	INC	R0		;
	BIC	#B0,R0		;POINT TO EVEN LOC
25$:	RESTORE	<R1>
	RTS	PC		;RETURN TO CALLER
;
; TYPE A CARRIAGE RETURN AND LINE FEED
;
; CALL	JSR	PC,CKCRLF
;
CKCRLF:	JSR	R0,CKTSTR
	.ASCIZ	<15><12>
	.EVEN
	RTS	PC
;
; TYPE A STRING PRECEEDED BY A CR/LF
;
; CALL	JSR	R0,CKTCRL
;	.ASCIZ	\TEXT\
;	.EVEN
;
CKTCRL:	JSR	PC,CKCRLF	;FIRST TYPE A CR/LF
;
; TYPE A MESSAGE ON THE CTY
; CALL	JSR	R0,CKTSTR	;CALL TYPE ROUTINE
;	.ASCIZ \TEXT\
;	.EVEN
;
CKTSTR:	JSR	PC,CKTTXT	;GO TYPE STRING
	RTS	R0
;
;TYPE A BLANK AND THE OCTAL CONTENTS OF R0
;
;	SIMILIAR TO CKTOCT
;
CKTBOC:	SAVE	<R1>
	MOV	#040,R1
	JSR	PC,CKTCHR
	BR	30$
;
; TYPE THE OCTAL CONTENTS OF R0
;
; CALL	JSR	PC,CKTOCT	;WITH ARG IN R0
;
CKTOCT:	SAVE	<R1>
30$:	SAVE	<R0>
	JSR	PC,50$
40$:	RESTORE	<R0>
	RESTORE	<R1>
	RTS	PC
;
;RECURSIVE BINARY TO ASCIC CONVERSION
;  PUSHES CURRENT VALUE IN R0 ONTO STACK, THEN DIVIDES BY 8 -
;    IF THE QUOTIENT IS NOT ZERO IT CALLS ITSELF, HENCE INTERLEAVING
;    INTERMEDIATE VALUES AND RETURN ADDRESSES - WHEN THE QUOTIENT
;    BECOMES ZERO, INTERMEDIATE VALUES ARE POPPED, AND THE LEAST
;    SIGNIFICANT VALUES ARE PRINTED IN TURN, WITH RETURN FALLING
;    BACK INTO THE PRINT ROUTINE - NOTICE THAT LEADING ZEROS ARE
;    AUTOMATICALLY SUPPRESSED, EXCEPT THE LONE ZERO OF A ZERO WORD
;
50$:	SAVE	<R0>		;STUFF CURRENT VALUE
	ROR	R0		;DIVIDE BY EIGHT
	ROR	R0		;
	ROR	R0		;
	BIC	#160000,R0	;CLEAR SPURIOUS CARRIES IN
	BEQ	60$		;SKIP TO PRINT WHEN QUOTIENT ZERO
	JSR	PC,50$		;  ELSE CALL SELF
60$:	RESTORE	<R1>		;POP INTERMEDIATE VALUE
	BIC	#^C7,R1		;SAVE LSD
	BIS	#60,R1		;SET BITS FOR ASCII CHARACTER
				;  AND DROP INTO CHARACTER PRINT
;
; TYPE THE SINGLE CHARACTER IN R1
;
; CALL	JSR	PC,CKTCHR	;WITH CHAR IN R1
;
CKTCHR:	CMPB	R1,#40		;DOES THIS NEED FILLER ?
	BHIS	80$		;
	CMPB	R1,#11		;IS CHAR A TAB (11)
	BNE	70$		;BRANCH IF NOT A TAB
	JSR	R0,CKTSTR	;GIVE SPACES FOR IT
	.BYTE	40,40,40,0	;SUBSTITUTE SPACES FOR TAB
	RTS	PC		;
				;
70$:	JSR	PC,75$		;TYPE CHAR FIRST THEN PAD IT WITH 4 NULLS
75$:	JSR	PC,80$		;
	CLR	R1		;
80$:	TST	CKTRPT		;CTY OUTPUT REPORT DEVICE?
	BPL	83$		;NO
81$:	TSTB	CTOSTS		;YES, TEST FOR STILL BUSY
	BPL	81$		;
	MOVB	R1,CTOCHR	;TYPE CHAR
83$:	TSTB	CKTRPT		;REMOTE DEVICE RECEIVING REPORT?
	BPL	86$		;NO
	JSR	PC,CKTREM	;YES, REPORT REMOTELY
86$:	RTS	PC		;
;
; BINARY TO DECIMAL ASCII CONVERSION AND OUTPUT
;
CKTDEC:	SAVE	<R0,R1,R2>	;
	MOV	#125$,R2	;SET DIVISOR POINTER
101$:	CLR	R1		;CLEAR QUOTIENT COUNTER
103$:	TST	-(R2)		;BACK DOWN INTO ARRAY
	BEQ	111$		;DONE ALL BUT UNITS
107$:	INC	R1		;UP QUOTIENT
	SUB	(R2),R0		;SUBTRACT CURRENT 10**N
	BGE	107$		;NOT NEGATIVE YET, LOOP AROUND
	ADD	(R2),R0		;WENT TOO FAR, GO BACK ONE
	DEC	R1		;COUNT BACK QUOTIENT
	BEQ	103$		;IF QUOTIENT IS ZERO, SUPPRESS IT
	BIS	#'0,R1		;CONVERT QUOTIENT DIGIT TO ASCII
	JSR	PC,CKTCHR	;TYPE DIGIT
	TST	(R2)		;DONE TO LSD?
	BNE	101$		;NO
111$:	RESTORE	<R2,R1,R0>	;RESTORE AND RETURN
	RTS	PC		;
124$:	.WORD	0,1.,10.,100.,1000.,10000. ;DECIMAL ORDERS OF MAGNITUDE
125$:				;125$ **ENDS** THE ARRAY
;
; GET A SINGLE CHAR FROM THE KEYBOARD
;	R1 WILL HAVE THE SEVEN BIT CHAR INPUT, OR
;	  WILL HAVE -1 IF THE ROUTINE HAD TO WAIT MORE
;	  THAN 30 SECONDS FOR A RESPONSE
;	IF THERE IS NO CTY, THE RETURNED CHAR WILL BE "N" (DEFAULT "NO")
; CALL	JSR	PC,CKGCHR
;
CKGCHR:	TST	CKTRPT		;KB EXIST?
	BPL	96$		;NO, DON'T LOOK FOR A CHARACTER
	SAVE	<R0,R2>		;YES, ENTER INPUT WAIT
	MOV	#500.,R2	;SET TIMEOUT COUNTERS
	CLR	R0		;
	MOV	#-1,R1		;ASSUME NO CHARACTER WILL BE RECEIVED
	TST	CTICHR		;CLEAR BUFFER
90$:	SOB	R0,90$		;THIS TAKES ABOUT 1/15 SECOND TO FALL THROUGH
	DEC	R2		;DO IT ENOUGH TIMES TO GET TO 30-60 SECONDS
	BEQ	95$		;NO INPUT WAS SEEN, RETURN WITH DEFAULT
	TSTB	CTISTS		;LOOK FOR CHAR
	BPL	90$		;NOT THERE YET
	MOVB	CTICHR,R1	;FINALLY GOT ONE, GRAB IT
	BIC	#^C177,R1	;KEEP ONLY INTERESTING BITS
	JSR	PC,CKTCHR	;TYPE IT BACK TO HIM (ECHO)
95$:	RESTORE	<R2,R0>		;
	RTS	PC		;
				;
96$:	MOV	#'N,R1		;NO CTY, RETURN "NO" FOR ANSWER
	RTS	PC		;
;
; GET A CHARACTER AND RETURN Z-BIT SET IF IT IS A "Y" (CASE INSENSITIVE) -
;    RETURN WITH C-BIT SET IF NO CHARACTER WAS RECEIVED
;
CKGYES:	JSR	PC,CKGCHR	;GET ANY CHARACTER
	CMPB	R1,#40		;TEST FOR IGNORED OR UNPRINTABLE
	BLT	97$		;NO CHARACTER
	BIS	#40,R1		;FORCE LOWER CASE FOR COMPARISON
	CMPB	R1,#'Y!40	;IS IT A "Y"?
	CLC			;RETURN Z-BIT FOR CALLER TO BRANCH ON
	RTS	PC		;
97$:	SEC			;NO REASONABLE CHARACTER TYPED
	RTS	PC		;
	    .DSABL LSB
.PAGE
.SBTTL	REMOTE OUTPUT HANDLER
;
CKTREM:				;
	; THIS ROUTINE WILL TAKE THE OUTPUT DIRECTED
	;   TO THE CTY AND SEND IT OVER A BUFFERED
	;   LINK TO BE OUTPUT ON A REMOTE DEVICE
	;
	; IF THE TRANSFER IS BUFFERED, RECEIPT OF A -1 BYTE
	;   SHOULD FORCE THE TRANSMISSION OF THE PARTIALLY FILLED
	;   BUFFER TO ENSURE THE UP TO DATE REPORTING OF VITAL
	;   MESSAGES (DEATH, DISEASE, FAMINE, ETC.)
				;
	MOV	R5,-(SP)	;
	BICB	#200,CKTRPT	;PREVENT ERROR LOOP IN THIS ROUTINE
	MOV	R0,-(SP)	;
	MOV	CK.PTR,R0	;PICK UP BUFFER FILL POINTER
	CMPB	R1,#-1		;IF CHARACTER IS -1,
	BNE	5$		;  (NOT)
	JSR	PC,CKBFSH	;WRITE OUT BUFFER
	BR	100$		;AND QUIT (DON'T STORE THE -1)
5$:	CMP	R1,#15		;IF CHARACTER IS <CR>,
	BNE	10$		;  (NOT)
	INC	CK.BFG		;SET FLAG
	BR	30$		;AND STORE IN BUFFER
10$:	CMP	R1,#12		;IF CHARACTER IS <LF>,
	BNE	20$		;  (NOT)
	TST	CK.BFG		;AND LAST CHAR WAS <CR>,
	BEQ	20$		;  (NOT)
	JSR	PC,CKBFSH	;WRITE OUT BUFFER
	
20$:	CLR	CK.BFG		;CLEAR <CR> FLAG
30$:	MOVB	R1,(R0)+	;STORE CHAR IN BUFFER
	CMP	R0,#CK.BFN	;IF AT END OF BUFFER,
	BNE	100$		;  (NOT)
	JSR	PC,CKBFSH	;WRITE OUT BUFFER
100$:	MOV	R0,CK.PTR	;REFRESH BUFFER FILL POINTER
	MOV	(SP)+,R0	;
	BISB	#200,CKTRPT	;RESET "REMOTE REPORTING" FLAG
	MOV	(SP)+,R5	;
	RTS	PC		;RETURN  TO CALLER
	
	
;  ROUTINE TO WRITE OUT A BUFFER
;
CKBFSH:	NOP		;CAN BE PATCHED TO BRANCH AROUND WRITE
	MOV	R1,-(SP)	;
	MOV	R2,-(SP)	;
	MOV	SP,CK.OSP	;SAVE OUR STACK POINTER
	MOV	CK.CSP,SP	;PICK UP CALLER'S STACK
	MOV	R0,R2		;CALCULATE
	SUB	#CK.BUF,R2	;  BUFFER LENGTH
	INC	R2		;  PLUS ONE FOR OPCODE
	MOV	#CK.COD,-(SP)	;ADDRESS MESSAGE START
	MOV	CK.DMC,R1	;PICK UP DMC CSR ADDRESS
	MOV	CK.CAL,R0	;CALL THE
	ADD	#SNDDRV,R0	;  DMC SEND
	SUB	#BT3STR,R0	;  ROUTINE
	JSR	PC,(R0)		;  IN LOADER
	TST	(SP)+		;GET RID OF BUFFER ADDRESS
	MOV	CK.OSP,SP	;RESTORE OUR STACK
	MOV	(SP)+,R2	;
	MOV	(SP)+,R1	;
10$:				;  *** THIS IS WHERE TO BRANCH TO ***
	MOV	#CK.BUF,R0	;RESET FILL POINTER TO START OF BUFFER
	RTS	PC
	
CK.COD:	.BYTE	22.		;MOP OP CODE
CK.BUF:	.BLKB	80.		;BUFFER
CK.BFN:	.BYTE	0		;  END OF BUFFER (1 BYTE SAFETY PAD)
	.EVEN			;
CK.BFG:	.WORD	0		;FLAG WORD
CK.PTR:	.WORD	CK.BUF		;BUFFER FILL POINTER
.PAGE
.SBTTL	UNEXPECTED BUS TRAP HANDLER
;
CKBUST:	CK11SC	<CKEDID>,<Bus error trap>
	.ASCIZ	\Bus Error trap from\
	.EVEN			;
	MOV	(SP),R0		;GET PC OF NEXT INST
	SUB	#2,R0		;MAKE PC WITHIN BAD INST
	JSR	PC,CKTBOC	;PRINT THE PC WHERE WE WERE DONE IN
;;;;	JMP	?		;FATAL BUS ERROR
20$:	HALT			;SOMEDAY WE MAY HAVE A REAL ABORT ROUTINE
	BR	20$		;  BUT FOR NOW, WE JUST HANG
;EDIT PAGE BREAK (FF)
.SBTTL	CK11SC/TRAP INSTRUCTION HANDLER
;
; TRAP INSTRUCTION HANDLER - WE GET HERE ON ERROR IN CHK11
;
;   AT HALT TIME R0 CONTAINS ADDRESS OF TRAP
;
CHKERR:	MOV	R0,-(SP)	;SAVE A WORKING REGISTER
	MOV	2(SP),-(SP)	;GET THE ADDRESS OF
	SUB	#2,(SP)		; THE TRAP INSTRUCTION
	MOV	@(SP)+,-(SP)	;REPLACE THE ADDRESS WITH THE INSTR
	BIT	#CKEDID,(SP)	;PRINT DEVICE ID+REG MSG?
	BEQ	11$		;NO
	BIS	#CKFERR,CHKFLG	;YES, REMEMBER WE HAD AN ERROR
	JSR	PC,CKDIDT	;
11$:	BIT	#CKEPC,(SP)	;TYPE PC MESSAGE?
	BEQ	14$		;NO
	JSR	R0,CKTCRL	;YES
	.ASCIZ	\	 Error at PC\
	.EVEN			;
	BIS	#CKFERR,CHKFLG	;REMEMBER WE HAD AN ERROR
	MOV	4(SP),R0	;GET ADDRESS
	TST	-(R0)		;  OF INSTRUCTION
	JSR	PC,CKTBOC	;PRINT SPACE AND ADDRESS
14$:	BIT	#CKEMSG!CKEMSE,(SP);ANY MSG TO DO?
	BEQ	36$		;NO
				;
	BIT	#CKENCL,(SP)	;YES, SUPPRESS CR/LF?
	BNE	20$		;YES
	JSR	PC,CKCRLF	;NO, DO CR/LF
20$:	BIT	#CKEDID!CKEGB,(SP);DETAIL FORMAT SPACES?
	BEQ	24$		;NO
	JSR	R0,CKTSTR	;YES
	.ASCIZ	"		"
	.EVEN			;
24$:	MOV	4(SP),R0	;GET MSG ADDRESS
	BIT	#CKEMSE,(SP)	;INDIRECT?
	BEQ	29$		;NO, INLINE
	MOV	(R0),R0		;YES, GET ACTUAL ADDRESS
29$:	JSR	PC,CKTTXT	;TYPE OUT MSG
	ADD	#2,4(SP)	;UPDATE RETURN ADDRESS
	BIT	#CKEMSG,(SP)	;WAS MSG INLINE?
	BEQ	36$		;NO
	MOV	R0,4(SP)	;YES, REPLACE RETURN ADDRESS
36$:	BIT	#CKEGB,(SP)	;SEE IF GOOD BAD PRINT OUT
	BEQ	40$		;BRANCH IF NOT THIS
	JSR	R0,CKTCRL	;
	.ASCIZ	\		Adr/Reg =\
	.EVEN			;
	MOV	10(SP),R0	;GET ADR OFF THE STACK
	JSR	PC,CKTBOC	;PRINT ADR
	JSR	R0,CKTSTR	;
	.ASCIZ	\  GD =\
	.EVEN
	MOV	14(SP),R0	;GET "GOOD"
	JSR	PC,CKTBOC	;PRINT IT
	JSR	R0,CKTSTR	;
	.ASCIZ	\  BD =\
	.EVEN
	MOV	12(SP),R0	;PRINT BAD STUFF
	JSR	PC,CKTBOC	;PRINT BAD
	JSR	R0,CKTSTR	;
	.ASCIZ	\  XOR =\
	.EVEN
	MOV	14(SP),-(SP)	;GET GOOD
	XOR	R0,(SP)		;LEAVE ONLY QUESTIONABLE BITS
	MOV	(SP)+,R0	;PRINT THEM
	JSR	PC,CKTBOC	;
40$:	BIT	#CKEFAT,(SP)	;FATAL ERROR?  HALT REQUIRED?
	BEQ	50$		;NO
	BIS	#CKFERR,CHKFLG	;YES, NOTE THAT WE HAD AN ERROR
	JSR	R0,CKTCRL	;
	.ASCIZ	\		Fatal Error\<377>
	.EVEN
	MOV	CKSPCD,R0	;PUT STOPCODE IN R0, 0 IS NOT TO BE DISPLAYED
	BEQ	45$		;IF 0
	HALT			;STOP CODE IN R0, PRESS CONTINUE
				; GIVES ADR WE CAME FROM
45$:	MOV	4(SP),R0	;ADDRESS OF RETURN FROM TRAP IN R0
	HALT			;FATAL ERROR - R0 CONTAINS ERROR ADDRESS
	JMP	CHK.11		;IF CONTINUE DO PROGRAM AGAIN.
50$:	BIT	#CKEGB,(SP)+	;WAS THERE A GD-BD PRINT? (POP SAVED INSTUCTION)
	BNE	55$		;YES, CLEAR STACK
	MOV	(SP)+,R0	;
	RTI			;  AND EXIT
				;
55$:	MOV	(SP)+,R0	;RESTORE WORKING REGISTER, CLEAN STACK
	MOV	(SP)+,4(SP)	;PC
	MOV	(SP)+,4(SP)	;PS
	TST	(SP)+		;CLEAN THE STACK
	RTI			;  THEN EXIT
.PAGE
CKSPCD:	.WORD	0		;CONTAINS STOPCODE ON FATAL ERROR
				;
CHKCHR:
				;
CKDA = .-CHKCHR			;DEVICE ADDRESS OFFSET
	.BLKW	1
				;
CKDV = .-CHKCHR			;DEVICE VECTOR OFFSET
	.BLKW	1
				;
CKPI = .-CHKCHR			;DEVICE PI LEVEL OFFSET
	.BLKW	1
				;
CKFLG = .-CHKCHR		;DEVICE FLAGS OFFSET
				; B0-B5 = # OF DQ11 SPECIAL CHAR
				; B15 = INTERRUPTED ON SYNC
	.BLKW	1
				;
CKSPC = .-CHKCHR		;SPECIAL CHAR OFFSET
	.BLKW	4		;SPECIAL CHARACTERS
;
.PAGE
		.REPT	0
	CKVECT	CD,1,1			;CD20 VECTOR SETUP
	CKVECT	CR,1,1			;CR11 VECTOR SETUP
	CKVECT	DH,2,16.		;DH11 VECTOR SETUP
	CKVECT	DJ,2,16.		;DJ11 VECTOR SETUP
	CKVECT	DL.E,2,16.		;DL11 VECTOR SETUP
	CKVECT	DM,1,16.		;DM11BB VECTOR SETUP
	CKVECT	DMC,2,16.		;DMC11 VECTOR SETUP
	CKVECT	DN,1,64.		;DN11 VECTOR SETUP
	CKVECT	DP,2,32.		;DP11 VECTOR SETUP
	CKVECT	DQ,2,16.		;DQ11 VECTOR SETUP
	CKVECT	DS,4,16.		;DS11 VECTOR SETUP
	CKVECT	DU,2,16.		;DU11 VECTOR SETUP
	CKVECT	DUP,2,16.		;DUP11 VECTOR SETUP
	CKVECT	DTE2,1,1		;DTE20 VECTOR SETUP
	CKVECT	KMC,2,3			;KMC11 VECTOR SETUP
	CKVECT	KW.P,1,1		;KW11-P VECTOR SETUP
	CKVECT	LE,1,2			;LP11 VECTOR SETUP
	CKVECT	LP,1,2			;LP20 VECTOR SETUP
	CKVECT	PP,1,1			;PP11 VECTOR SETUP
	CKVECT	PR,1,1			;PR11 VECTOR SETUP
	CKVECT	P6,1,16.		;PA611P VECTOR SETUP
	CKVECT	R6,1,16.		;PA611R VECTOR SETUP
	CKVECT	TC,1,1			;TC11 VECTOR SETUP
	CKVECT	TM,1,1			;TM11 VECTOR SETUP
	CKVECT	RC,1,1			;RC11 VECTOR SETUP
	CKVECT	RF,1,1			;RF11 VECTOR SETUP
	CKVECT	RH,1,1			;RH11 (RJP04) VECTOR SETUP
	CKVECT	RP,1,1			;RP11-C VECTOR SETUP
	CKVECT	TA,1,1			;TA11 VECTOR SETUP
	CKVECT	RK,1,1			;RK11 VECTOR SETUP
	CKVECT	RX,1,1			;RX11 VECOR SETUP
		.ENDR	;END OF SUPPRES VECTORS
;
CKMG01:	.ASCIZ	\Mem Err\<377>
CKMG02:	.ASCIZ	\Bit did not clear\<377>
CKMG03:	.ASCIZ	\Bit did not set\<377>
CKMG04:	.ASCIZ	\Interrupt did not occur\<377>
CKMG05:	.ASCIZ	\Interrupted to wrong vector\<377>
CKMG06:	.ASCIZ	\not found\<377>
CKMG07:	.ASCIZ	\interrupted when not enabled\<377>
;
	.EVEN
CKBLK=CKINTS			;REMOVE THIS AREA AS A BUFFER FOR THE DH11 TEST
;
	.BLKW	40		;STACK FOR CHECK-11
CHKSTK	=.			;END OF STACK
.PAGE
.SBTTL MODULE END
.SBTTL PROGRAM END
	CHKEND=	.	;COMPUTE AND PRINT PROGRAM SIZE
;
;	EEEEEEEEEEEEEE	NN          NN	DDDDDDDDDD	!!
;	EE		NNNN        NN	DD        DD	!!
;	EE		NN  NN      NN	DD          DD	!!
;	EE		NN  NN      NN	DD          DD	!!
;	EEEEEEEEEE	NN    NN    NN	DD          DD	!!
;	EE		NN    NN    NN	DD          DD	!!
;	EE		NN      NN  NN	DD          DD	!!
;	EE		NN        NNNN	DD        DD		
;	EEEEEEEEEEEEEE	NN          NN	DDDDDDDDDD	!!
;
;
;**********************************************************************
;
; END OF CHK11 - THE ONLY ONCE ONLY SYSTEM DIAGNOSTIC YOU'LL EVER NEED
;
;**********************************************************************
;
.PAGE
	.TITLE	TERBOT - TERTIARY NETWORK BOOTSTRAP
;
; MODULE DESCRIPTION:
;
;	TERTIARY BOOT PART II
;
;
;
; DISTRIBUTED SYSTEMS SOFTWARE ENGINEERING
;
; IDENT HISTORY:
;
; 1.00	10-FEB-78
;	VERSION 2.0 RELEASE
; 2.00	16-OCT-78
;	MODIFICATION FOR DN20/DN200 USE WITH CHECK11
;
  
;+
; **-BT3STR-START OF TERTIARY NETWORK LOADER
;
; INPUTS:
;
;	R1 = CSR ADDRESS OF LOAD DEVICE
;	SP = HIGHEST MEMORY ADDRESS OF THE MACHINE
;	ALL THE CODE BETWEEN 'BT3STR' AND 'BT3END' HAS BEEN RELOCATED
;	TO THE TOP OF MEMORY.
;	THE FOLLOWING DATA LOCATIONS HAVE BEEN INITIALIZED:
;		$DEVTP - ASCII NAME OF THE LOAD DEVICE
;		$UNIT  - UNIT NUMBER OF THE LOAD DEVICE
;		KT11   - FLAG TO INDICATE EXISTANCE OF MEMORY MANAGEMENT
;
;
;-
;
	.DSABL	AMA
BT3STR:	CLR	R0		;START WITH LOAD 0
INIT:	JSR	PC,INIDRV	;INIT DEVICE
	TSTB	KT11		;MEMORY MANAGEMENT ENABLED ?
	BEQ	10$		;IF EQ, NO - LEAVE HIGHEST LOAD ADDRESS ALONE
	BIC	#160000,2(SP)	;OTHERWISE REDUCE IT TO A VIRTUAL ADDRESS THROUGH APR0
10$:				;

;
;	SEND REQUEST OPERATING SYSTEM BOOT MESSAGE
;
;	MESSAGE SENT IS:
;	CODE 8-REQUEST PROGRAM
;	CODE(1),DEVTYPE(1),STADDR(1),PGMTYPE(1)
;
SNDOS:	CLR	LOADED+0	;Nothing loaded so far
	CLR	LOADED+2
	MOV	(SP),R5		;MESSAGE BUFFER ADDR
	MOV	#DEVTYP,R2	;  DEVICE
	SWAB	R2		;  TYPE AND
	ADD	#8.,R2		;  CODE
	MOV	R2,(R5)+	;  INTO MESSAGE
	MOV	#1001,(R5)+	;STATION ADDR + OPERATING SYSTEM REQUEST
SENDIT:	MOV	#4,R2		;MESSAGE LENGTH
SNDIT:
;
;	Check if update wanted on console
;
	JSR	PC,PRGRSS
;
	MOV	#20.,TMR	;(time this)
	JSR	PC,SNDDRV	;TO SEND DRIVER
	BNE	INIT		;START AGAIN
;
;	RECEIVE A MESSAGE FROM THE LINK
;
;
	MOV	#BUFSIZ,R2	;SET BUFFER SIZE
	MOV	#20.,TMR	;(time this)
	JSR	PC,RCVDRV	;TO RECEIVE DRIVER
	BNE	ERR		;ERROR ON RECEIVE
	MOV	(SP),R3		;BUFFER ADDR
;
;	PROGRAM LOAD WITH AND WITHOUT TRANSFER ADDR
;	R2-MESSAGE BYTE COUNT(WITHOUT CODE)
;	R3-MESSAGE ADDR(BYTE FOLLOWING CODE)
;	R4-CODE
;
;	MESSAGES RECEIVED ARE:
;	CODE 0-PGM LOAD WITH TRANSFER ADDR
;	CODE(1),LDNUM(1),LDADDR(4),IMAGE(N),XADDR(4)
;
;	CODE 2-PGM LOAD WITHOUT XFER ADDR
;	CODE(1),LDNUM(1),LDADDR(4),IMAGE(N)
;
;	CODE 20-PARAMETERS WITH TRANSFER ADDRESS
;	CODE(1),LDNUM(1),PARAMETERS,XADDR(4)
;	PARAMETERS:  ENTRY,ENDMARK
;	ENTRIES:
;	PARTYPE (1):B	PARAMETER TYPE #
;	PARLENGTH (1):B	# OF BYTES IN PARVALUE
;	PARVALUE (1):B	PARAMETER VALUE ACCORDING TO PARTYPE AND PARLENGTH
;	PARAMETER TYPE		LENGTH		VALUE
;		1		1 TO 6		ASCII NODE NAME
;		2		  2		BINARY NODE NO.
;		3		1 TO 6		ASCII HOST NODE NAME
;		4		  2		binary host node no.
;	ENDMARK (1):B  = 0
;
;
;	MESSAGE RETURNED IS:
;	CODE 10-REQUEST PROGRAM LOAD
;	CODE(1),LDNUM(1),ERROR(1)
;
;
PGMLD0:	MOVB	(R3)+,R4	;SAVE CODE
	DEC	R2		;SUBTRACT CODE LENGTH
	CMPB	R4,#2		;IS IT LOAD WITH XFER ADDR
	BEQ	PGMLD2		;YES
	CMPB	R4,#20.		;IS IT A PARAMETERS MESSAGE
	BEQ	5$		;IF EQ, YES
	TSTB	R4		;IS IT LOAD WITHOUT XFER ADDR
	BNE	SNDOS		;NO
5$:	SUB	#4.,R2		;SUBTRACT XFER ADDR LENGTH
PGMLD2:	TSTB	(R3)		;IS IT LOAD 0
	BEQ	10$		;YES, RESET LOAD NUMBER
	CMPB	(R3),R0		;DOES IT MATCH REQUESTED LOAD
	BNE	ERR		;NO, ASK AGAIN
10$:	MOVB	(R3)+,R0	;SET LOAD NUMBER
	INCB	R0		;SET TO NEXT REQUESTED
	DEC	R2		;DECREMENT REMAINING COUNT
;	BLE	NODAT		;IF LE, NO DATA IN THIS LOAD
;
;
; GET LOAD ADDRESS
;
	CMPB	R4,#20.		;IS THIS A PARAMETERS MESSAGE ?
	BEQ	PARM		;IF EQ, YES - EXTRACT PARAMETERS
	MOV	(R3)+,R5	;LOAD ADDR
	TSTB	KT11		;MEMORY MANAGEMENT ENABLED ?
	BEQ	20$		;IF EQ, NO - SKIP EXTENDED MEMORY COMPUTATION
	MOV	R5,-(SP)	;USE THE HIGH BYTE OF R5 AS THE LOW ORDER
	SWAB	(SP)		;    BYTE OF THE REAL MEMORY ADDRESS
	MOVB	(R3),1(SP)	;THE NEXT BYTE IN THE MESSAGE IS THE HIGH ORDER ADDRESS
	BIC	#7,(SP)		;POSITION FOR MULTIPLES OF 1K WORDS
	ASL	(SP)		;...
	ASL	(SP)		;...
	MOV	(SP)+,@#KISAR0	;SET UP THE MAPPING REGISTER
	BIC	#^C<3777>,R5	;BUILD A VIRTUAL ADDRESS USING APR0
20$:	TST	(R3)+		;SKIP OVER HIGH ORDER WORD OF LOAD ADDRESS
	SUB	#4.,R2		;SUBTRACT LOAD ADDR LENGTH
	BLE	NODAT		;IF LE, NO DATA
	ADD	R2,LOADED+0	;Account for data loaded
	ADC	LOADED+2
;
; MOVE THE DATA BUT DON'T OVERWRITE THE LOADER
;
30$:	TSTB	KT11		;MEMORY MANAGEMENT ENBALED ?
	BEQ	40$		;IF EQ, NO - SKIP EXTENDED ADDRESS CHECK
	CMP	@#KISAR0,@#KISAR6 ;IS THE BLOCK RELOCATION BIAS POINTING BEYOND THE LOAD
	BNE	50$		;IF NE, IT MIGHT BE - DONT NEED VIRTUAL ADDRESS CHECK
40$:	CMP	R5,2(SP)	;IS THE VIRTUAL ADDRESS TOO LARGE ?
50$:	BHIS	LDERR		;IF HIS, YES - LOAD ERROR
	MOVB	(R3)+,(R5)+	;MOVE BYTE TO REQUESTED LOCATION
	DEC	R2		;DECREMENT COUNT
	BGT	30$		;MORE TO MOVE
	
;
; CHECK FOR TRANSFER ADDRESS
;
NODAT:	TSTB	R4		;IS IT LOAD WITH XFER ADDR
	BEQ	XFER		;IF EQ, YES - TRANSFER TO PROGRAM
	
;
; REQUEST NEXT BLOCK
;
ACKLD:	CLR	R3		;CLEAR ERROR BYTE
SNDER:	MOV	(SP),R5		;BUFFER ADDR
	MOVB	#10.,(R5)+	;REQUEST PGM LOAD CODE
	MOVB	R0,(R5)+	;REQUESTED LOAD NUMBER
	MOV	#3,R2		;SET FOR ACK CNT
	MOV	R3,(R5)+	;SET ERROR STATUS
	BEQ	SNDIT
	INC	R2		;ONE MORE IF ERROR
	BR	SNDIT
	
;
; LOADER OVERWRITE ERROR
;
LDERR:	MOV	#0,R3		;SET ERROR CODE
	BR	SNDER		;
	
;
; TRANSFER ADDRESS ERROR
;
XFERR:	MOV	#2,R3		;SET ERROR CODE
	BR	SNDER		;
	
;
;	ERROR ON RECEIVE
;	SEND EITHER REQUEST PROGRAM OR LOAD
;
ERR:	TSTB	R0		;HAVE WE STARTED XFER YET
	BEQ	SNDOS		;NOT YET,REQUEST PROGRAM
	BR	ACKLD		;ALREADY STARTED, REQUEST LOAD
	
;
; PARAMETERS MESSAGE WITH TRANSFER ADDRESS
;
PARM:	MOV	R3,R4		;SAVE PARAMETER ADDRESS
	ADD	R2,R3		;SKIP OVER ALL PARAMETERS
	ADD	#BUFSIZ+64.,2(SP);LAST 32. WORDS		GP013078
	ADD	#TOP32,2(SP)	;32 WORD BLOCK AT END
	SUB	#BT3STR,2(SP)	;HAD BEEN SAVED
	CMP	#DEVTYP,#12.	;USING DMC?			GP020678
	BNE	9$		;NO				GP020678
	ADD	#128.,2(SP)	;YES, ADJUST ADDRESS MORE	GP020678
9$:	MOV	2(SP),R2	;				GP013078
	TSTB	KT11		;MEMORY MANAGEMENT		GP021278
	BEQ	12$		;NO				GP021278
	MOV	@#KISAR6,@#KISAR0;				GP021278
12$:	CLR	(R2)+		;CLEAR BINARY AREA
	MOV	#12.,R5		;PAD OUT REST
10$:	MOVB	#40,(R2)+	;WITH SPACES
	DEC	R5
	BNE	10$
	clr	(r2)		;make room for host node number 
11$:	MOV	2(SP),R2	;GET BACK ADDRESS		GP013078
	TSTB	(R4)		;CHK FOR END			GP013078
	BEQ	XFER		;IF 0, NO MORE DATA		GP013078
	CMPB	#2,(R4)		;BINARY? (TYPE=2)		GP012578
	BEQ	15$		;NO				GP012578
	cmpb	#4,(r4)		;host node number ?
	bne	13$		;nop
	add	#6.,r2		;where it goes in top32
13$:	TST	(R2)+		;BEYOND BINARY AREA		GP012578
	DECB	(R4)		;CHK IF HOST NAME (TYPE=3)	GP013178
	BEQ	15$		;IF EQ, NODE NAME		GP013178
	ADD	#6,R2		;GET TO PROPER AREA
15$:	TSTB	(R4)+		;GET COUNT
	MOVB	(R4)+,R5
20$:	MOVB	(R4)+,(R2)+	;MOVE NAME OR NUMBER
	DEC	R5
	BNE	20$
	BR	11$		;CHK FOR MORE			GP013078
	
;
;	IF FINAL LOAD THEN TRANSFER
;
XFER:	MOV	2(SP),R2	;GET BACK ADDRESS               ;**NEW**
	TST	(R2)+		;TO NAME AREA                   ;**NEW**
	CMPB	(R2),#40	;VALID NAME?                    ;**NEW**
	BNE	5$		;YES                            ;**NEW**
	CLR	(R2)		;NO, NULL IT                    ;**NEW**
5$:	ADD	#6,R2		;NEXT NAME AREA                 ;**NEW**
	CMPB	(R2),#40	;SAME TEST                      ;**NEW**
	BNE	10$                                             ;**NEW**
	CLR 	(R2)                                            ;**NEW**
10$:	MOVB	(R3)+,-(SP)	;LOW BYTE TO STACK
	MOVB	(R3)+,1(SP)	;HIGH BYTE
	MOV	(SP)+,R3	;GET THE TRANSFER ADDRESS
	TSTB	KT11		;IS THERE MEMORY MANAGEMENT?
	BEQ	70$		;IF EQ NO
	CLR	@#KISAR0	;SET APR TO LOW 4K
	CMP	R3,#140000	;IS THE ADDRESS WITHIN BOUNDS?
	BLO	80$		;IF LO YES
	MOV	@#KISAR6,@#KISAR2 ;NEED TO "RELOCATE" THIS CODE
	BIC	#100000,PC	;USE APR2 INSTEAD OF APR6
	MOV	#1400,@#KISAR6	;SET TO PROPER 4K BOUNDARY
	BR	80$		;CLEAN UP AND XFER
;
70$:	CMP	R3,SP		;TRANSFER WITHIN BOOT3?
	BHIS	XFERR		;IF HIS, YES - SEND ERROR
	
;
; ACKNOWLEDGE THE LAST BLOCK TO FINISH THE LOAD
;
80$:	MOV	(SP),R5		;GET BUFFER ADDRESS
	MOVB	#10.,(R5)+	;REQUEST PROGRAM LOAD
	MOVB	R0,(R5)+	;REQUESTED LOAD NUMBER
	CLR	(R5)+		;NO ERROR
	MOV	R3,R0		;SAVE TRANSFER ADDRESS
	MOV	#2,R2		;SET LENGTH
	JSR	PC,SNDDRV	;SEND THE LAST ACK
	MOV	#10.,R2		;KILL ENOUGH TIME FOR THE LAST ACK TO GO
	MOV	R0,R5		;RESTORE TRANSFER ADDRESS
1$:	DEC	R0		;DECREMENT INNER LOOP
	BNE	1$		;KEEP GOING TILL ZERO
	DEC	R2		;DECREMENT OUTER LOOP
	BNE	1$		;ONCE MORE
25$:	CLR	R3
	BISB	$UNIT,R3	;SET LOAD UNIT NO.
	MOV	$DEVTP,R4	;AND DEVICE TYPE
	MOV	#-1,R1		;TO INDICATE DOWN LINE LOAD
	MOV	#-1,R2		;SAME
	MOV	R5,PC		;DO THE TRANSFER
;
;	Display our progress on request
;
PRGRSS:	TSTB	@#CTISTS	;If character ready
	BPL	90$		;then
	MOVB	@#CTICHR,R4	;pick it up
	BIC	#^C177,R4	;and clear parity.
	CMPB	#'T-100,R4	;If ^T
	BNE	90$		;then display our progress.
	MOV	PC,R3		;Get address
	ADD	#BTLNM-.,R3	;of our message
	MOV	LOADED+0,R5	;and
	MOV	LOADED+2,R4	;bytes loaded
	DIV	#2000.,R4	;(in KW)
	CALL	100$
	CALL	100$
	CALL	100$
	BISB	#'0,BTLNM-1	;Insure not all blanks.
	MOV	PC,R3		;Get
	ADD	#BTTXT-.,R3	;text string.
80$:	TSTB	@#CTOSTS	;If the console
	BPL	80$		;is ready,
	MOVB	(R3)+,@#CTOCHR	;then send a character.
	TSTB	(R3)		;If more,
	BNE	80$		;then send it.
90$:	RTS	PC

100$:	ASHC	#-16.,R4
	BEQ	110$
	DIV	#10.,R4
	ADD	#'0,R5
	MOVB	R5,-(R3)
	RTS	PC
110$:	MOVB	#' ,-(R3)
	RTS	PC
;
; LOCAL DATA (RELOCATED WITH THE LOADER)
;
$DEVTP::.BLKW	1		;ASCII NAME OF DEVICE TYPE USED DOWN-LINE
$UNIT::	.BLKB	1		;PHYSICAL DEVICE NO. OF LOAD UNIT
BTTXT:	.ASCII	/Loaded XXX/
BTLNM:	.ASCIZ	/KW/<13.><10.>
	.EVEN
LOADED:	.WORD	0,0		;Bytes loaded
KT11:	.BYTE	0		;KT-11 FLAG
	.BYTE	0		;RESERVED
BT3END	=.			;END OF TERTIARY LOADER



	.sbttl	DMC BOOT DRIVER
;
; MODULE DESCRIPTION:
;
;	DMC DRIVER FOR BOOT (AND PANIC)
;
;
;
; DISTRIBUTED SYSTEMS SOFTWARE ENGINEERING
;
; IDENT HISTORY:
;
; 1.00	10-FEB-78
;	VERSION 2.0 RELEASE
;  .01	25-JAN-79  L. WEBBER	LW0001
;		WHEN CALCULATING PHYSICAL ADDRESSES, DON'T ASSUME
;		THEY ARE IN PAGE 6
;
;
;
; DEFINE THE MOP DEVICE CODE
;
	DEVTYP==12.
	
;
; LOCAL SYMBOL DEFINITIONS
;
KISAR0=172340                                                                   ;LW0001
REBOOT==173356                                                                  ;**-1
TMR::	.WORD	0			;TIMER INDICATOR FOR PANIC

;+
; **-INIDRV-DEVICE INITIALIZATION
;
; INPUTS:
;
;	R1 = CSR ADDRESS OF DEVICE
;
;	0(SP) = RETURN ADDRESS
;	2(SP) = BUFFER ADDRESS
;	4(SP) = HIGHEST ADDRESS BEFORE BUFFERS AND DEVICE STORAGE
;
; OUTPUTS:
;
;	THE DMC USES THE MEMORY PRECEEDING THE DATA BUFFER FOR ITS
;	BASE TABLE.  THE DEVICE INITIALIZATION ADJUSTS THE ENTRY ON
;	THE STACK TO REFLECT THIS.
;-
;
INIDRV::MOV	2(SP),R4	;VIRTUAL BASE ADDR
	SUB	#128.,R4	;LEAVE ENOUGH ROOM FOR THE BASE TABLE
	MOV	R4,4(SP)	;ADJUST THE HIGHEST LOAD ADDRESS CELL
	MOV	R4,BASE		;SAVE FOR INTERNAL DEVICE INITIALIZATIONS
	CLR	TMR
	
INIT1:	BIS	#40000,(R1)	;MASTER CLEAR DMC
	MOV	#100000,(R1)	;TURN DMC ON
	MOV	BASE,R4		;GET BASE ADDRESS
	JSR	PC,GTMADR	;GET REAL ADDR
	MOVB	#43,(R1)	;RQI + BASE
	JSR	PC,DMCIN	;GIVE TO DMC
	MOV	#2400,R3	;SET MOP & HALF DUPLEX
	CLR	R4		;FILLER REG
	MOVB	#41,(R1)	;RQI + CNTLI
	JSR	PC,DMCIN
	CLZ			;UNSUCCESSFUL
	RTS	PC		;RETURN TO CALLER
;
;	SET PARAMETERS TO DMC
;	R4=FIRST PARM
;	R3=SECOND PARM
;
DMCIN:	TSTB	(R1)		;RDYI SET ?
	BMI	INOK		;YES
	TSTB	2(R1)		;RDYO SET ?
	BPL	DMCIN		;NO
	JSR	PC,DMCOUT	;CHECK COMPLETION
	BEQ	DMCIN		;AGAIN
	RETURN			;ERROR - RETURN TO CALLER
INOK:	MOV	R4,4(R1)	;TO FIRST HALF DMC PORT
	MOV	R3,6(R1)	;TO SECOND HALF DMC PORT
	BIC	#40,(R1)	;CLEAR RQI-GIVE TO DMC
1$:	TSTB	(R1)		;RDYI CLEAR ?
	BMI	1$		;NOT YET
	SEZ			;SUCCESSFUL
5$:	RETURN			;RETURN TO CALLER



;+
; **-RCVDRV-RECEIVE A BLOCK FROM THE DEVICE
; **-SNDDRV-TRANSMIT A BLOCK ON THE DEVICE
;
; INPUTS:
;
;	R1 = CSR ADDRESS
;	R2 = MAXIMUM BLOCK LENGTH TO RECEIVE, OR
;	     BLOCK LENGTH TO TRANSMIT
;
;	0(SP) = RETURN ADDRESS
;	2(SP) = BUFFER ADDRESS
;
; OUTPUTS:
;
;	Z-BIT SET:
;	R2 = ACTUAL LENGTH OF BLOCK RECEIVED
;	(SP) = BUFFER ADDRESS
;
;	Z-BIT CLEAR:
;	AN ERROR WAS DETECTED ON THE DEVICE
;	THE STACK IS AS DESRIBED ABOVE
;-
;
	.ENABL	LSB
	
RCVDRV::MOVB	#44,(R1)	;RQI + BA/CC + RCV
	BR	10$		;
	
SNDDRV::MOVB	#40,(R1)	;RQI + BA/CC + XMT

10$:	MOV	2(SP),R4	;GET ADDRESS OF THE BUFFER
	JSR	PC,GTMADR	;GET REAL ADDR OF BUFFER
	BIS	R2,R3		;SET BUFFER SIZE
	JSR	PC,DMCIN	;GIVE TO DMC
	CLR	R5
20$:	TSTB	2(R1)		;TEST RDYO SET
	BMI	21$
	DEC	R5		;COUNT ON IT
	BNE	20$
	TST	TMR		;NOT YET, NEED TIMER?
	BEQ	20$		;NO
	DEC	TMR
	BGT	20$		;DONE IT LONG ENOUGH?
	BR	INIT1		;YES, RE_INITIALIZE AND QUIT
;
;	CHECK COMPLETION FROM DMC-11
;
;
21$:	CLR	TMR		;YES, CLEAR IND.
DMCOUT:	MOV	6(R1),R2	;GET LENGTH OR ERROR BITS
	BIC	#140000,R2	;CLEAR MEMORY ENTENSION BITS
	BITB	#3,2(R1)	;BA/CC OR CTLO
	BEQ	30$		;IF EQ, BA/CC COMPLETION
	BIT	#1730,R2	;IS IT FATAL ERROR ?
	BNE	INIT1		;IF NE, CLEAR AND REINITIALIZE THE DEVICE
	
30$:	CLRB	2(R1)		;CLEAR RDYO (SETS Z-BIT)
	RETURN			;RETURN
	
	.DSABL	LSB
	
;
;	GET REAL ADDR FROM VIRTUAL ADDR
;	VIRTUAL ADDR IN R4
;	REAL ADDR IN R4(LOW 16 BITS)
;	REAL ADDR IN R3(HIGH 2 BITS) BITS 14 AND 15
;	IF STACK ADDR JUST BELOW 4K BOUNDARY THEN REAL MACHINE
;	IF STACK ADDR JUST ABOVE 4K BOUNDARY THEN VIRTUAL MACHINE
;	THIS WORKS FOR PRESENT BOOT ONLY ***BEWARE***
;
;
GTMADR:	MOV	R4,R3		;CALCULATE THE                                  ;LW0001
	ASH	#-12.,R3	;  PAGE NUMBER                                  ;LW0001
	BIC	#^C16,R3	;  (TIMES 2 FOR INDEXING)                       ;LW0001
	MOV	KISAR0(R3),R3	;PICK UP THE PROPER BIAS                        ;LW0001
	ASL	R4		;SEPARATE BIAS FROM DISP                        ;**-3
	ASL	R4		;
	SWAB	R4		;BIAS TO LOW BYTE
	BISB	R4,R3		;COMPUTE PHYS BLOCK ADDR
	ROR	R3		;2 BITS OF PHYS ADDR...
	ROR	R4		;TO DISP BYTE
	ASR	R3		;
	ROR	R4		;
	CLRB	R4		;GET RID OF GARBAGE
	BISB	R3,R4		;PHYS BLOCK TO ADDR
	SWAB	R4		;REAL ADDR AGAIN
	CLRB	R3		;CLEAR LOW OF REMAINDER
	ASR	R3		;MOVE ADDR BITS 16 & 17
	ASR	R3		;TO BITS 6 & 7 OF REG
	SWAB	R3		;TO BITS 14 & 15 OF REG
	RETURN			;BACK TO CALLER WITH ADDR
BMREAL:	CLR	R3		;HIGH ADDR BITS ARE ZERO
	RETURN			;BACK TO CALLER WITH ADDR
	
	
;
; LOCAL DATA STORAGE
;
BASE:	.BLKW	1		;START OF BASE TABLE
				;RESERVED AREA MOVED TO SEPARATE


	.END	START