Google
 

Trailing-Edge - PDP-10 Archives - BB-P363B-SM_1985 - mcb/loaders/dtemop.mac
There are no other files named dtemop.mac in the archive.
;<SROBINSON>DTEMOP.MAC.5 13-Apr-81 11:11:42, Edit by SROBINSON
;NET:<SROBINSON>DTEMOP.MAC.3  7-Apr-81 11:17:34, Edit by SROBINSON
	.IIF NDF S$$CLD!T$$RLD .TITLE DTEMOP -- DTE20 MOP MODE BOOTSTRAP
	.IIF DF S$$CLD .TITLE DTEMPS -- DTE20 MOP SECONDARY BOOTSTRAP
	.IIF DF T$$RLD .TITLE DTEMPT -- DTE20 MOP TERTIARY BOOTSTRAP
	.SBTTL	TITLE PAGE
	.IDENT	"V01.02"
;
;
;                    COPYRIGHT (c) 1980, 1981, 1982
;                    DIGITAL EQUIPMENT CORPORATION
;                        Maynard, Massachusetts
;
;     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:	DTEMOP
;
; IDENT HISTORY:
;
;	1.00	22-JAN-77	TOM PORCHER
;		RELEASE 3A AND 4 BASE
;
;	1.01	13-APR-79	LEE WEBBER
;		MODIFY LOAD PARAMETER HANDLING TO THE STANDARD.
;
;	1.02	13-APR-81	Scott Robinson
;		Change Edit 1.01 to make Secondary work again
;
	.SBTTL	MACROS AND DEFINITIONS
;
; PARAMETERS (DEFINED IN PARAMETER MODULE)
;
;	S$$CLD=	0		;SECONDARY LOADER (FOR TERTIARY) IF DEFINED
;	T$$RLD=	0		;TERTIARY LOADER IF DEFINED
;
; PARAMETERS
;
;**	D$$BUG=	0		;DEBUG VERSION IF DEFINED
	E$$CHK=	0		;ERROR CHECKING IF DEFINED
	D$$CHK=	0		;DTE-20 CONSISTENCY CHECKING IF DEFINED
	M$$CHK=	0		;MEMORY LIMIT CHECKING IF DEFINED
.IF DF T$$RLD
	L$$DPR=	0		;ALLOW LOAD PARAMETERS IF DEFINED
	M$$XSZ=	1024.		;MAX SIZE IS 1K BYTES (0.5K WORDS)
	M$$MGE=	0		;MEMORY MANAGEMENT IF DEFINED
	T$$32K=	0		;ALLOW DTE20 TRANSFERS OVER 32K BOUNDARIES IF DEFINED
.IFF
	M$$XSZ=	512.		;MAX SIZE IF PROGRAM IS 512. BYTES (256. WORDS)
.ENDC
;
;
; MISC. MCALLS
;
	.MACRO	CALL,A
	JSR	PC,A		;CALL A
	.ENDM

	.MACRO	RETURN
	RTS	PC
	.ENDM

;
; MACROS
;
.MACRO DEBUG,OP,MSG,ALTOP
.IF DF D$$BUG
	 OP			;MSG
.IF NDF PASS2
.PRINT .-MOP ;MSG
.ENDC
.IFF
	 ALTOP
.ENDC
.ENDM DEBUG
;
.MACRO ERR,CND,MSG,WHERE,?LABEL
.IF DF D$$BUG
	 .IIF IDN <CND>,<R>,
	 .IIF IDN <CND>,<NE>,BEQ LABEL
	 .IIF IDN <CND>,<EQ>,BNE LABEL
	 .IIF IDN <CND>,<PL>,BMI LABEL
	 .IIF IDN <CND>,<MI>,BPL LABEL
	 .IIF IDN <CND>,<VC>,BVS LABEL
	 .IIF IDN <CND>,<VS>,BVC LABEL
	 .IIF IDN <CND>,<CC>,BCS LABEL
	 .IIF IDN <CND>,<CS>,BCC LABEL
	 .IIF IDN <CND>,<GE>,BLT LABEL
	 .IIF IDN <CND>,<LT>,BGE LABEL
	 .IIF IDN <CND>,<GT>,BLE LABEL
	 .IIF IDN <CND>,<LE>,BGT LABEL
	 .IIF IDN <CND>,<HI>,BLOS LABEL
	 .IIF IDN <CND>,<LOS>,BHI LABEL
	 .IIF IDN <CND>,<HIS>,BLO LABEL
	 .IIF IDN <CND>,<LO>,BHIS LABEL
.IFTF
	DEBUG HALT,<ERROR: "MSG">,<B'CND	WHERE'MOPERR>
.IFT
LABEL:
.ENDC
.ENDM ERR
;
.MACRO FIT,BASE,SIZE,STUFF
.IF DF SIZE&PASS2
.IF G <<.-BASE>-SIZE>
 .ERROR <<.-BASE>-SIZE> ; TOO MUCH STUFF
.IFF
 .PRINT <SIZE-<.-BASE>> ; FREE FOR STUFF
.ENDC
.ENDC
.ENDM FIT
;
;
; GENERAL BIT DEFINITIONS
;
BIT0=	000001
BIT1=	000002
BIT2=	000004
BIT3=	000010
BIT4=	000020
BIT5=	000040
BIT6=	000100
BIT7=	000200
BIT8=	000400
BIT9=	001000
BIT10=	002000
BIT11=	004000
BIT12=	010000
BIT13=	020000
BIT14=	040000
BIT15=	100000
;
;
; MOP DEFINITIONS
;
M.PMLT=	0.			;MEMORY LOAD WITH TRANSFER
M.PMLD=	2.			;MEMORY LOAD
M.PRMD=	4.			;REQUEST MEMORY DUMP
M.PEMM=	6.			;ENTER MOP MODE
M.PRPR=	8.			;REQUEST PROGRAM
M.PRML=	10.			;REQUEST/ACKNOWLEDGE MEMORY LOAD
M.PMMR=	12.			;MOP MODE RUNNING
M.PMDP=	14.			;MEMORY DUMP
M.PDAP=	16.			;(REMOTE-11) DAP ENVELOPE
M.PEAM=	18.			;(REMOTE-11) ENTER REMOTE-11 ASCII MODE
M.PLDP=	20.			;PROGRAM DATA
M.PLBT=	24.			;LOOPBACK TEST
;
;
; CPU REGISTER DEFINITIONS
;
SWR=	177570			;SWITCH REGISTER
PS=	177776			;PROCESSOR STATUS WORD
	PR7=	7*BIT5		;PRIORITY 7
;
; MEMORY MANAGEMENT REGISTER DEFINITIONS
;
SR0=	177572			;STATUS REGISTER 0
;
KISDR0=	172300			;KERNAL PAGE DESRIPTOR 0
KISDR1=	172302			; . . 1
KISDR2=	172304			; . . 2
KISDR3=	172306			; . . 3
KISDR4=	172310			; . . 4
KISDR5=	172312			; . . 5
KISDR6=	172314			; . . 6
KISDR7=	172316			; . . 7
;
KISAR0=	172340			;KERNAL PAGE ADDRESS REGISTER 0
KISAR1=	172342			; . . 1
KISAR2=	172344			; . . 2
KISAR3=	172346			; . . 3
KISAR4=	172350			; . . 4
KISAR5=	172352			; . . 5
KISAR6=	172354			; . . 6
KISAR7=	172356			; . . 7
;
;
; DTE20 REGISTER DEFINITIONS
;
DLYCNT=	0			;DELAY COUNTER
	BUSA17=	BIT15		;UNIBUS ADDRESS BIT 17
	BUSA16=	BIT14		;UNIBUS ADDRESS BIT 16
	DLYMSK=	37777		;DELAY COUNTER
DEXWD3=	2			;DEPOSIT/EXAMINE WORD 3
DEXWD2=	4			; . . 2
DEXWD1=	6			; . . 1
TENAD1=	10			;KL-10 MEMORY ADDRESS 1
TENAD2=	12			; . . 2
TO10BC=	14			;TO -10 BYTE (WORD) COUNT
TO11BC=	16			;TO -11 BYTE (WORD) COUNT
	TO11IB=	BIT15		;INTERRUPT BOTH -10 AND -11 WHEN DONE
	TO11BM=	BIT13		;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 REGISTER 2
	DRESET=	BIT6		;(W) DTE20 RESET
CSTAT=	34			;CONTROL/STATUS REGISTER
	TO10DN=	BIT15		;(R) TO -10 TRANSFER DONE
	DON10C=	BIT14		;(W) CLEAR TO -10 DONE
	TO10ER=	BIT13		;(R) TO -10 TRANSFER ERROR
	ERR10C=	BIT12		;(W) CLEAR TO -10 TRANSFER ERROR
	TO11DB=	BIT11		;(R/W) TO -11 DOORBELL
	INT11C=	BIT10		;(W) CLEAR TO -11 DOORBELL
	TO10DB=	BIT8		;(R/W) TO -10 DOORBELL
	TO11DN=	BIT7		;(R) TO -11 TRANSFER DONE
	DON11C=	BIT6		;(W) CLEAR TO -11 DONE
	TO11ER=	BIT1		;(R) TO -11 TRANSFER ERROR
	ERR11C=	BIT0		;(W) CLEAR TO -11 TRANSFER ERROR
DIAG3=	36			;DIAGNOSTIC/CONTROL REGISTER 3
	TO10BM=	BIT0		;(W) TO -10 BYTE MODE
	.SBTTL	MOVE TO TOP OF PHYSICAL MEMORY
;
; SEONDARY LOADER:
; THE BM873-YF, -YG, -YH, -YJ ROM LOADS THIS 256. WORD (512. BYTE) PROGRAM
; STARTING AT LOCATION 0, THEN TRANSFERS TO LOCATION 0.
;
; TERTIARY LOADER:
; THE SECONDARY LOADER LOADS THIS 1K WORD (2048. BYTE) PROGRAM
; AND TRANSFERS TO IT AT ITS TRANSFER ADDRESS "DTEMOP"
;
;
; THE FOLLOWING REGISTERS ARE LEFT BY THE ROM:
;	R1 --	ADDRESS OF DTE20 STATUS WORD "CSTAT"
;
;
DTEMOP:
	DEBUG HALT,<BOOTSTRAP>,NOP ;(0) MARK START OF BOOTSTRAP
.IF DF T$$RLD
	MOV	#30$,@#4	;(2,4,6) SET UP TIMEOUT TRAP
	MOV	#PR7,@#6	; TO TRAP TO US
.IFF
	BR	10$		;(2) SKIP OVER TIMEOUT CODE
;
; TIMEOUT VECTOR-- USED TO FIND TOP OF MEMORY
;
	.WORD	30$,PR7		;(4,6) WHERE TO GO ON NXM (FIRST ON KT-11, THEN MEMORY S
;
10$:
;
; WAIT FOR TO -11 DOORBELL IF NOT CLEARED BY ROM
;
	TSTB	(R1)		;TO -11 DONE?
	BPL	15$		;NO-- DOOBELL HAS BEEN CLEARED
	BIT	#TO11DB,(R1)	;DOORBELL RINGING?
	BEQ	10$		;NO-- WAIT
15$:
.ENDC
;
; FIND TOP BLOCK OF PHYSICAL MEMORY WHERE WE WILL FIT
;
	MOV	#STACK-4,SP	;SET STACK
	MOV	#160000,R0	;START AT EXTERNAL PAGE IF NO KT11
.IF DF M$$MGE
	MOV	#77406,R2	;SET MAX SIZE FOR AN APR
	MOV	R2,@#KISDR0	;SET MAP FOR THIS CODE (THIS WILL TRAP TO 30$ IF NO KT11
	MOV	R2,@#KISDR1	;SET MAP FOR FINDING MEMORY
	MOV	R2,@#KISDR7	; THEN FOR EXTERNAL PAGE
	CLR	@#KISAR0	;SET MAP SEGMENT 0 TO THIS CODE
	MOV	#7600,@#KISAR1	;START MEMORY LOOKING AT EXTERNAL PAGE
	MOV	#7600,@#KISAR7	;ALSO MAP EXTERNAL PAGE
	MOV	#1,@#SR0	;ENABLE SEGMENTATION
	MOV	#20000,R0	;POINT TO WHERE MAPPING REGISTER 1 MAPS
	MOV	#20$,@#4	;SET TIMEOUT TO KT11 FLAVOR
20$:
	CMP	(SP)+,(SP)+	;REMOVE TRAP
	SUB	#M$$XSZ/100,@#KISAR1 ;COUNT DOWN BY OUR SIZE
	TST	(R0)		;TRAP BACK TO 20$ IF NON-EX MEM
;
; FOUND TOP OF PHYSICAL MEMORY-- NOW COMPUTE PHYSICAL ADDRESS
;
	MOV	@#KISAR1,R5	;GET PHYSICAL ADDRESS (RIGHT-SHIFTED 6 BITS)
	ASL	R5		;SHIFT
	ASL	R5		; EXTENSION
	ASL	R5		;  BITS TO
	ASL	R5		;   BITS 15-14
	MOV	R5,R4		;COPY IT
	BIC	#^C<BUSA17!BUSA16>,R4 ;TRIM TO RIGHT SIZE
	ASL	R5		;MAKE R5
	ASL	R5		; PHYSICAL ADDRESS
	BR	40$		;GO ON TO MOVE
.IFTF
;
; HERE IF WE MUST FIND TOP OF MEMORY WITHOUT MEMORY MANAGEMENT
;
30$:
	CMP	(SP)+,(SP)+	;REMOVE TRAP FROM STACK
	SUB	#M$$XSZ,R0	;DOWN BY ANOTHER BLOCK
	TST	(R0)		;TRAP TO 30$ IF STILL NXM
;
; FOUND TOP OF PHYSICAL MEMORY
;
	MOV	R0,R5		;COPY PHYSICAL ADDRESS
.IFT
	CLR	R4		;MEMORY EXTENSION= 0
	MOV	#240,CLRSR0	;CHANGE "CLR (SP)" (SR0) TO NO-OP
.IFF
	CLR	DLYCNT-CSTAT(R1) ;SET MEMORY EXTENSION BITS FOR DTE20 TO 0
.ENDC
;
; WE NOW HAVE R0 POINTING TO THE TOP BLOCK IN MEMORY.
; SINCE THIS IS POSITION-INDEPENDENT, WE CAN MOVE UP THERE NOW.
;
; REGISTERS:
;	R0 --	VIRTUAL ADDRESS OF WHERE TO MOVE CODE
;	R1 --	VIRTUAL ADDRESS OF DTE20 "CSTAT" REGISTER
;	R4 --	PHYSICAL ADDRESS OF WHERE TO MOVE CODE (BITS 17-16, IN BITS 15-14)
;	R5 --	PHYSICAL ADDRESS OF WHERE TO MOVE CODE (BITS 15-0)
;
40$:
	MOV	R0,SP		;COPY VIRTUAL ADDRESS
	MOV	R0,PARMAD	;CALCULATE START
	ADD	#M$$XSZ-64.,PARMAD ;  OF PARAMETER AREA
	MOV	#MOP,R2		;SET SOURCE ADDRESS
50$:
	MOV	(R2)+,(SP)+	;MOVE A WORD
	CMP	R2,#STACK	;MOVED ALL THE CODE?
	BLO	50$		;NO-- KEEP ON MOVIN'
	JMP	(R0)		;OFF AND RUNNING
	.SBTTL	MOP PROCESSOR
;
; THIS POSITION-INDEPENDENT CODE EXECUTES IN THE TOP BLOCK OF PHYSICAL MEMORY
;
; REGISTERS:
;	R1 --	VIRTUAL ADDRESS OF DTE20 "CSTAT" REGISTER
;	R4 --	PHYSICAL ADDRESS OF MOVED CODE (BITS 17-16, IN BITS 15-14)
;	R5 --	PHYSICAL ADDRESS OF MOVED CODE (BITS 15-0)
;	SP --	STACK POINTER (TOP OF VIRTUAL MEMORY)
;
; PAGE REGISTERS:
;	0 --	MAPS TO PHYSICAL 0
;	1 --	MAPS TO THIS CODE
;	7 --	MAPS TO EXTERNAL PAGE
;
MOP:
	DEBUG HALT,<MOVED TO TOP OF PHYSICAL>
.IF DF E$$CHK!D$$CHK!M$$CHK
	MOV	#DRESET,DIAG2-CSTAT(R1) ;RESET ALL TRANSFERS IN PROGRESS
	MOV	PC,SP		;SET STACK
	ADD	#STACK-.,SP	; BACK, JACK
	CLRB	LODNUM		;START LOAD AT ZERO
.IF DF L$$DPR
	CLRB	PRGDAT		;MARK NO PROGRAM DATA YET
.ENDC
.ENDC
;
; SEND "REQUEST PROGRAM" MESSAGE TO THE -10
;
	MOV	#REQOPS-MOP,R0	;GET ADDRESS OF MOP "REQUEST PROGRAM"
	CALL	DTESND		;SEND IT TO -10
;
; WAIT FOR -10 TO SEND US SOMETHING-- DOORBELL WILL RING
;
MOPWAT:
	BIT	#TO11DB,(R1)	;DOORBELL RINGING?
	BEQ	MOPWAT		;NO-- WAIT UNTIL -10 RINGS US
;
; THE FIRST TWO BYTES ARE THE BYTE COUNT.
;
	MOV	#RCVMSG-MOP,R0	;GET ADDRESS OF BYTE COUNT WORD
	MOV	(PC),R3		;SET LARGE COUNT
	MOV	#2,R2		;SET BYTE COUNT
	CALL	DTERCV		;RECEIVE BYTE COUNT
;
; THE NEXT BYTE IS THE MOP FUNCTION CODE.
; THE NEXT BYTE IS THE LOAD NUMBER.
;
	MOV	BYTCNT,R3	;GET BYTE COUNT NOW
	MOV	#2,R2		;ONE BYTE MOP FUNCTION, ONE BYTE LOAD NUMBER
	CALL	DTERCA		;RECEIVE MOP CODE, ADDRESS IN R0
.IF DF E$$CHK
;
; VERIFY MOP FUNCTION
;
	MOVB	MOPFNC,R2	;GET MOP FUNCTION
	BEQ	10$		;(M.PMLT) MEMORY LOAD W/TRANSFER-- OK
	CMPB	R2,#M.PLDP	;PROGRAM DATA?
	BEQ	10$		;YES-- OK
	CMPB	R2,#M.PMLD	;MEMORY LOAD?
	ERR NE,<INVALID MOP FUNCTION CODE RECEIVED>,MOPFER
10$:
;
; VERIFY LOAD NUMBER
;
.IFTF
	MOVB	RCVLDN,R2	;IS LOAD 0?
.IFT
	BEQ	20$		;YES-- ALWAYS OK
	CMPB	R2,LODNUM	;THIS RIGHT LOAD?
	ERR NE,<WRONG LOAD NUMBER RECIEVED>,MOPFER
20$:
.ENDC
	INCB	R2		;BUMP LOAD NUMBER
	MOVB	R2,LODNUM	;STORE LOAD NUMBER
;
; RECEIVE DATA INTO MEMORY
;
	MOV	#4,R2		;SET TO GET LOAD ADDRESS
	CMPB	MOPFNC,#M.PLDP	;PROGRAM DATA?
	BNE	40$		;NO-- USE ADDRESS
	ADD	#PRGDAT-LODADR,R0 ;YES-- POINT TO PROGRAM DATA STORAGE AREA
	NEG	R2		;GET -4 FOR TRANSFER ADDRESS
	ADD	R3,R2		;GET SIZE LEFT
	BR	60$		;AND RECEIVE PROGRAM DATA
;
40$:
	CALL	DTERCA		; INTO LODADR
	BLE	70$		;ONLY TRANSFER -- DO THAT
	CMPB	MOPFNC,#M.PMLD	;MEMORY LOAD ONLY?
	BEQ	42$		;YES-- ALL IS DATA
	SUB	#4,R2		;NO-- SAVE TRANSFER FOR LATER
42$:
	MOV	LODADR+0,R0	;GET LOW ADDRESS BITS
.IF DF M$$MGE
.IF DF M$$CHK
	MOV	R0,-(SP)	;ALSO SAVE AS ADDRESS RANGE
.IFTF
	MOV	LODADR+2,-(SP)	;GET HIGH ADDRESS BITS
.IFT
	BIT	#^C<BIT1!BIT0>,(SP) ;EXTRA BITS SET?
	ERR NE,<LOAD REQUEST ABOVE 128K>,MOPFER
.IFTF
	ASR	(SP)		;SHIFT
	ROR	(SP)		; TO
	ROR	(SP)		;  BITS 15-14
	BIC	#^C<BUSA17!BUSA16>,(SP) ;TRIM EXCESS
.IFT
	MOV	(SP),DLYCNT-CSTAT(R1) ;SET MEMORY BITS
	ADD	R2,2(SP)	;COMPUTE FINAL TRANSFER ADDRESS
	BCC	44$		;NO CARRY-- GO ON
	ADD	#BUSA16,(SP)	;CARRY INTO THE HIGH PART
	ERR CS,<LOAD REQUEST WRAPS AROUND 128K>,MOPFER
44$:
	CMP	(SP)+,R4	;VERIFY HIGH ADDRESS
	ERR HI,<LOAD REQUEST ABOVE LOADER>,MOPFER
	BLO	46$		;CHECK LOW ADDRESS ONLY IF EQ
	CMP	(SP),R5		;VERIFY LOW ADDRESS
	ERR HI,<LOAD REQUEST ON OR ABOVE LOADER>,MOPFER
46$:
	TST	(SP)+		;REMOVE LOW ADDRESS
.IFF
	MOV	(SP)+,DLYCNT-CSTAT(R1) ;SET MEMORY BITS
.ENDC
.IFF
.IF DF M$$CHK
	TST	LODADR+2	;MAKE SURE HIGH ADDRESS IS ZERO
	ERR NE,<LOAD REQUEST ABOVE LOADER>,MOPFER
	MOV	R0,-(SP)	;ALSO SAVE LOW ADDRESS FOR COMPARE
	ADD	R2,(SP)		;COMPUTE FINAL TRANSFER ADDRESS
	CMP	(SP)+,R5	;VERIFY LOW ADDRESS
	ERR HI,<LOAD REQUEST ON OR ABOVE LOADER>,MOPFER
.ENDC
.ENDC
60$:
	CALL	DTERCA		;RECEIVE THEM BYTES
	BLE	80$		;ALL DONE-- DO ANOTHER REQUEST
;
; READ TRANSFER ADDRESS INTO LODADR
;
	MOV	#LODADR-MOP,R0	;POINT BACK TO VIRTUAL MEMORY
	CALL	DTERCV		;READ THE ADDRESS INTO VIRTUAL MEMORY
70$:
.IF DF S$$CLD
	CMPB	MOPFNC,#M.PMLD	;MEMORY LOAD ONLY?
	BNE	90$		;NO-- DO THE TRANSFER
.IFTF
;
; SEND REQUEST FOR NEXT MEMORY LOAD SEGMENT TO THE -10
;
80$:
	MOV	#REQMLD-MOP,R0	;GET ADDRESS OF MOP "REQUEST/ACKNOWLEDGE MEMORY LOAD"
	CALL	DTESND		;SEND IT TO -10
.IFT
	BR	MOPWAT		;AND WAIT FOR ANOTHER REQUEST
;
90$:
.IFF
	CMPB	MOPFNC,#M.PMLD	;MEMORY LOAD ONLY?
	BEQ	MOPWAT		;YES-- WAIT FOR NEXT REQUEST
.ENDC
;
; TRANSFER TO ADDRESS NOW IN LODADR.
;
.IF DF M$$CHK
	TST	LODADR+2	;MUST HAVE A VIRTUAL (16-BIT) TRANSFER ADDRESS
	ERR NE,<TRANSFER ADDRESS ABOVE 32K>,,95$
.ENDC
.IF DF L$$DPR
	MOV	PC,R4		;  DATA FROM THE
	ADD	#<PRGDAT-.>,R4	;  RECEIVE BUFFER
	MOV	PARMAD,R5	;  TO THE STANDARD
	CLR	(R5)+		;CLEAR OUT BINARY AREA
	MOV	#6,R0		;CLEAR OUT NODE
110$:	MOV	#20040,(R5)+	;  AND HOST
	SOB	R0,110$		;  NAME AREAS
112$:	MOV	PARMAD,R5	;ADDRESS BEGINNING OF STANDARD AREA
	TSTB	(R4)		;IF THERE ARE NO MORE PARMS,
	BEQ	118$		;  GET OUT OF LOOP
	CMPB	(R4),#2		;NODE NUMBER -
	BEQ	115$		;  WE'RE POSITIONED RIGHT NOW
	TST	(R5)+		;PAST BINARY AREA
	DECB	(R4)		;IF NOT
	BEQ	115$		;  NODE NAME,
	ADD	#6,R5		;  BUMP TO HOST AREA
115$:	INCB	(R4)+		;PAST PARM TYPE (MAKE IT NON-ZERO)
	MOVB	(R4)+,R0	;PICK UP PARM LENGTH
116$:	MOVB	(R4)+,(R5)+	;MOVE PARM TO
	SOB	R0,116$		;  STANDARD AREA
	BR	112$		;GO DO NEXT PARM
.ENDC
;

118$:	MOV	R1,SP		;COPY DTE STATUS ADDRESS
	MOV	R1,R0		;  (ALSO TO HERE)
.IF DF L$$DPR
	MOVB	PRGDAT,R1	;IF THERE IS
	BEQ	120$		;  PROGRAM DATA,
	MOV	#-1,R1		;  FLAG THE FACT
	MOV	R1,R2		;  IN R1 AND R2
.ENDC
.IF DF M$$MGE
120$:	ADD	#DEXWD3-CSTAT,SP ;POINT TO DEXWD3, DEXWD2 FOR CODE
	MOV	(PC)+,(SP)+	;(DEXWD3)
CLRSR0:	 CLR	(SP)		;TURN OFF SEGMENTATION
	MOV	(PC)+,(SP)+	;(DEXWD2)
	 JMP	(R3)		;TRANSFER TO LOADED CODE.
	MOV	LODADR,R3	;SET TRANSFER ADDRESS
	MOV	#SR0,SP		;ALSO WHERE TO DISABLE SEGMENTATION
	DEBUG HALT,<TRANSFER ADDRESS READY>
	JMP	DEXWD3-CSTAT(R0) ;NOW TURN OFF SEGMENTATION AND TRANSFER.
.IFF
	DEBUG HALT,<TRANSFER ADDRESS READY>
	JMP	@LODADR		;TRANSFER TO IT.
.ENDC
.IF DF E$$CHK!D$$CHK!M$$CHK
;
; MOP FORMAT ERROR-- READ REST OF MOP MESSAGE AND REQUEST PROGRAM AGAIN
;
.IF DF E$$CHK!M$$CHK
MOPFER:
	MOV	#1,R2		;READ ONE BYTE
	MOV	#RCVMSG,R0	; INTO RCVMSG
	CALL	DTERCV		;  FROM -10
	BGT	MOPFER		;NOT DONE-- READ ANOTHER
;	BR	MOPERR		;DONE-- ABORT
.ENDC
;
; ERROR-- BACK TO REQUEST PROGRAM AGAIN
;
MOPERR:
.IF LT <<.-MOP>-256.>
	BR	MOP		;SEND REQUEST PROGRAM
.IFF
	JMP	MOP		;SEND REQUEST PROGRAM
.ENDC
.ENDC
	.SBTTL	DTE SUBROUTINES
;
; DTESND -- SEND MESSAGE TO DTE20 FROM VIRTUAL
;	R0 --	ADDRESS WITHIN MOVED CODE TO SEND DATA FROM (BYTE COUNT WORD)
;	R1 --	VIRTUAL ADDRESS OF DTE20 "CSTAT" REGISTER
;	R4 --	PHYSICAL ADDRESS OF MOVED CODE (BITS 17-16, IN BITS 15-14)
;	R5 --	PHYSICAL ADDRESS OF MOVED CODE (BITS 15-0)
;
DTESND:
	MOV	#DON10C!ERR10C,(R1) ;RESET TO10DN AND TO10ER
	MOV	#TO10BM,DIAG3-CSTAT(R1) ;SET TO -10 BYTE MODE
.IF DF M$$MGE
	MOV	R4,DLYCNT-CSTAT(R1) ;SET MEMORY EXTENSION BITS
.ENDC
.IF DF D$$CHK
	MOV	R0,-(SP)	;SAVE ADDRESS
.IFTF
	ADD	R5,R0		;CONVERT TO PHYSICAL
	MOV	R0,TO10AD-CSTAT(R1) ;SET ADDRESS OF MOP MESSAGE
.IFT
	ADD	#2,R0		;DON'T FORGET THE BYTE COUNT!
	ADD	PC,(SP)		;CONVERT OFFSET WITHIN "MOP" TO VIRTUAL
	ADD	#MOP-.,(SP)	; . .
	ADD	@(SP)+,R0	;UPDATE ADDRESS BY BYTE COUNT
.ENDC
	MOV	#TO10DB!INT11C,(R1) ;RING -10'S DOORBELL WITH THIS MESSAGE
;
; WAIT FOR TO -10 TRANSFER
;
10$:
.IF DF E$$CHK
	BIT	#TO10DN!TO10ER,(R1) ;DONE OR ERROR?
	BEQ	10$		;NOT DONE OR ERROR-- WAIT
	ERR PL,<TO -10 TRANSFER ERROR>
.IFF
	TST	(R1)		;DONE?
	BPL	10$		;NO-- WAIT
.ENDC
.IF DF D$$CHK
	CMP	R0,TO10AD-CSTAT(R1) ;TRANSFER REQUESTED NUMBER OF BYTES?
	ERR NE,<TO -10 TRANSFER WRONG NUMBER OF BYTES>
.ENDC
	RETURN			;RETURN FROM DTESND
;
; DTERCV -- RECEIVE MESSAGE FROM DTE20 VIRTUAL
;	R0 --	ADDRESS WITHIN MOVED CODE TO STORE DATA
;	R1 --	VIRTUAL ADDRESS OF DTE20 "CSTAT" REGISTER
;	R2 --	BYTE COUNT TO BE RECEIVED
;	R3 --	GLOBAL BYTE COUNT
;	R4 --	PHYSICAL ADDRESS OF MOVED CODE (BITS 17-16, IN BITS 15-14)
;	R5 --	PHYSICAL ADDRESS OF MOVED CODE (BITS 15-0)
;
DTERCV:
.IF DF M$$MGE
	MOV	R4,DLYCNT-CSTAT(R1) ;SET EXTENDED MEMORY BITS
.ENDC
	ADD	R5,R0		;MAKE PHYSICAL ADDRESS
;
; DTERCA -- RECEIVE FROM DTE20
;	R0 --	PHYSICAL RECEIVE ADDRESS (BITS 15-0)
;	R1 --	VIRTUAL ADDRESS OF DTE20 "CSTAT" REGISTER
;	R2 --	BYTE COUNT TO BE RECEIVED
;	R3 --	GLOBAL BYTE COUNT
;
DTERCA:
	MOV	R0,TO11AD-CSTAT(R1) ;SET ADDRESS
	ADD	R2,R0		;UPDATE ADDRESS
.IF DF T$$32K
	BCC	10$		;NO BOUNDARY-- OK
	BEQ	10$		;EXACTLY A BOUNDARY-- OK ALSO
;
; THE REQUESTED TRANSFER CROSSES A 32K BOUNDARY-- WE MUST
;  DO THE TRANSFER IN TWO PIECES
;
	MOV	R0,-(SP)	;SAVE RESIDUAL COUNT ABOVE BOUNDARY
	SUB	R0,R2		;CHANGE THIS COUNT TO JUST BELOW BOUNDARY
	CLR	R0		;SET FINAL ADDRESS= 0
	CALL	10$		;DO THE FIRST PART OF THE TRANSFER
	MOV	(SP)+,R2	;GET RESIDUAL COUNT
	MOV	R2,R0		;THAT'S FINAL ADDRESS, ALSO
10$:
.ENDC
	MOV	#DON11C!ERR11C,(R1) ;RESET TO11DN AND TO11ER
	SUB	R2,R3		;LAST TRANSFER?
	BEQ	20$		;YES-- SET TO11IB TO INDICATE "DONE" TO BOTH PROCESSORS
.IF DF E$$CHK
	ERR LT,<TO -11 MESSAGE TO SHORT>
.ENDC
	BIS	#TO11IB,R2	;CLEAR TO11IB (WHEN WE NEG R2)
20$:
	NEG	R2		;NEGATE BYTE COUNT
	BIC	#^C<TO11IB!TO11BM!TO11CM>,R2 ;CLEAR UNUSED BITS
.IF DF E$$CHK
	ERR EQ,<TO -11 ZERO BYTE TRANSFER>
.ENDC
	MOV	R2,TO11BC-CSTAT(R1) ;START TRANSFER
;
; WAIT FOR TO -11 TRANSFER
;
30$:
.IF DF E$$CHK
	BITB	#TO11DN!TO11ER,(R1) ;DONE OR ERROR?
	BEQ	30$		;NOT DONE OR ERROR-- WAIT
	ERR PL,<TO -11 TRANSFER ERROR>
.IFF
	TSTB	(R1)		;DONE?
	BPL	30$		;NO-- WAIT
.ENDC
.IF DF D$$CHK
	CMP	R0,TO11AD-CSTAT(R1) ;TRANSFER PROPER NUMBER OF BYTES?
	ERR NE,<TO -11 TRANSFER WRONG NUMBER OF BYTES>
.ENDC
.IF DF T$$32K
	TST	R0		;THIS TRANSFER CROSS A 32K BOUNDARY?
	BNE	40$		;NO-- ALL OK
	ADD	#BUSA16,DLYCNT-CSTAT(R1) ;YES-- BUMP ADDRESS BITS
40$:
.ENDC
	MOV	R3,R2		;GET REMAINING COUNT, AND TST IT
	RETURN			;RETURN FROM DTERCV/DTERCA
	.SBTTL	DATA
;
; MOP MESSAGE "REQUEST PROGRAM"
;
REQOPS:
	.WORD	REQOPZ		;(2 BYTES) BYTE COUNT
	.BYTE	M.PRPR		;(0) FUNCTION = REQUEST PROGRAM
	.BYTE	20.		;(1) DEVICE TYPE = DTE20/11
	.BYTE	1		;(2) STATION ADDRESS = 1
.IF DF S$$CLD
	.BYTE	1		;(3) PROGRAM TYPE = TERTIARY LOADER
.IFF
	.BYTE	2		;(3) PROGRAM TYPE = OPERATING SYSTEM
.ENDC
REQOPZ=	.-REQOPS-2
	.EVEN
;
; MOP MESSAGE "REQUEST/ACKNOWLEDGE MEMORY LOAD"
;
REQMLD:
	.WORD	REQMLZ		;(2 BYTES) BYTE COUNT
	.BYTE	M.PRML		;(0) FUNCTION = REQUEST/ACKNOWLEDGE MEMORY LOAD
LODNUM:	.BYTE	0		;(1) LOAD NUMBER (START AT 0)
REQMLZ=	.-REQMLD-2
;
; LOAD PARAMETER BLOCK FOR PROGRAM
;
PARMAD:	.WORD	0		;VIRTUAL ADDRESS OF STANDARD PROGRAM DATA AREA
PRGDAT:
	.BYTE	0		;FIRST BYTE INDICATES EXISTENCE
	FIT DTEMOP,M$$XSZ,<CODE>
	.BLKB	100.-1		;LOAD PARAMETERS FOR PROGRAM
;
; RECEIVED MOP MESSAGE
;
	.EVEN
RCVMSG:
BYTCNT:	.BLKW	1		;BYTE COUNT
MOPFNC:	.BLKB	1		;MOP FUNCTION
RCVLDN:	.BLKB	1		;LOAD NUMBER RECEIVED
LODADR:	.BLKB	4		;LOAD ADDRESS/TRANSFER ADDRESS
;
; STACK
;
	.EVEN
	.BLKW	4
STACK:
;
	FIT MOP,M$$XSZ,<MOVED CODE>
	.SBTTL	END
PASS2:
	.END	DTEMOP