Google
 

Trailing-Edge - PDP-10 Archives - CFS_TSU04_19910205_1of1 - update/ihssrc/dnload.mac
There are 24 other files named dnload.mac in the archive. Click here to see a list.
;GALAXY:<IBMCOM.LATEST>DNLOAD.MAC.5  7-Dec-88 10:42:14, Edit by Lomartire
; 4(21) Don't send the LF after a CR in TALK10
;<IBMCOM.BUILD>DNLOAD.MAC.2  2-Mar-88 13:11:19, Edit by WORLEY
; 4(20) And update the Copyright
; 4(17) Fix error message presentation in TYPERR so MIC will work
; 4(16) GCO 4.2.1024 - Add START and STOP protocol commands.
;<DN65-DEVELOPMENT>DNLOAD.MAC.11, 31-Jan-80 13:34:48, EDIT BY WEISBACH
; 3(15) Add copyright notice.
; 3(14) Fix a 2020 SYSERR reporting bug.
;<DN65-DEVELOPMENT>DNLOAD.MAC.10,  8-Oct-79 11:20:18, EDIT BY WEISBACH
; 3(13) Allow defaults only on filespec extension.
;<DN65-DEVELOPMENT>DNLOAD.MAC.9,  4-Sep-79 14:45:56, EDIT BY WEISBACH
; 3(12) Add some SYSERR reporting.
; 3(11) Remove defaults from COMND JSYS
;<WEISBACH>DNLOAD.MAC.16, 10-Aug-79 11:41:36, EDIT BY WEISBACH
;<WEISBACH>DNLOAD.MAC.16, 10-Aug-79 11:41:36, EDIT BY WEISBACH
; 3(10) Require that user be wheel or operator
;<WEISBACH>DNLOAD.MAC.11, 23-Jul-79 09:37:44, EDIT BY WEISBACH
; 3(7) Permit .BIC files to be interpreted as .BIN files (for Field Service
; diagnostics).
; 3(6) Fix bug to allow conversing with a diagnostic.
; 3(5) Allow listening over a DZ line for the 2020.
;<DN65-DEVELOPMENT>DNLOAD.MAC.5, 15-May-79 14:44:48, EDIT BY WEISBACH
; 3(4)	Fix bug which causes console FE to get dumped instead of
;	DN60 FE.
;<WEISBACH>DNLOAD.MAC.9,  2-May-79 13:29:16, EDIT BY WEISBACH
; 3(3)	Add command defaults
;<WEISBACH>DNLOAD.NEW.5,  6-Apr-79 16:25:37, EDIT BY WEISBACH
; [3(2)]	Add functionality to load and dump over a DTE.
;<WEISBACH>DNLOAD.NEW.4,  6-Apr-79 15:57:53, EDIT BY WEISBACH
; [3(1)]	Close loader files when loading complete or error occurs.
;<WEISBACH>DNLOAD.NEW.13, 22-Feb-79 14:05:42, EDIT BY WEISBACH
;Use the provided routine to process End-of-Command
;<WEISBACH>DNLOAD.NEW.19,  5-Feb-79 22:56:09, EDIT BY WEISBACH
;In MAKMLX inserted code to circumvent bug in secondary loader.  Loader
;will not accept a Xfer without load address.  Added dummy load.

;
;
;			  COPYRIGHT (c) 1979, 1980, 1988
;                    DIGITAL EQUIPMENT CORPORATION
;
;     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.
;
TITLE DNLOAD -- PROGRAM TO LOAD AND DUMP SECONDARY PDP11S

	SEARCH MONSYM, MACSYM
	.REQUIRE SYS:MACREL
	SALL

; ACCUMULATOR DEFINITIONS

	T1=1		;TEMPORARY
	T2=2		;TEMPORARY
	T3=3		;TEMPORARY
	T4=4		;TEMPORARY
	Q1=5		;PRESERVED
	Q2=6		;PRESERVED
	Q3=7		;PRESERVED
	P1=10		;PRESERVED
	P2=11		;PRESERVED
	P3=12		;PRESERVED
	P4=13		;PRESERVED
	P5=14		;PRESERVED
	P6=15		;PRESERVED (CAUTION, USED BY SOME MACROS IN MACSYM)
	CX=16		;RESERVED FOR SUPPORT CODE
	P=17		;PUSH-DOWN POINTER

; VERSION NUMBER DEFINITIONS

VMAJOR==4		;MAJOR VERSION OF DNLOAD
VMINOR==2		;MINOR VERSION NUMBER
VEDIT==21		;EDIT NUMBER
VWHO==0			;GROUP WHO LAST EDITED PROGRAM (0=DEC DEVELOPMENT)

VDNLOAD== <VWHO>B2+<VMAJOR>B11+<VMINOR>B17+VEDIT

NCHPW==5		;NUMBER OF ASCII CHARACTERS PER WORD
BUFSIZ==200		;SIZE OF INPUT TEXT BUFFER
ATMSIZ==BUFSIZ		;SIZE OF ATOM BUFFER FOR COMND JSYS
GJFSIZ==.GJRTY+2	;SIZE OF GTJFN BLOCK USED BY COMND JSYS
FDBSIZ==.CMDEF+2	;SIZE OF FUNCTION DESCRIPTOR BLOCK
DCOSIZ==50		;DIAGNOSTIC COMMAND BUFFER SIZE
TXTSIZ==50		;TEXTI BLOCK SIZE
PDLEN==50		;PUSH-DOWN STACK LENGTH

;SYSERR DEFINITIONS
;DEFINITIONS FOR SYSERR BLOCK HEADER
HRC%RB==1		;EVENT RECORDED BY TOPS20
HRC%FM==1		;HEADER FORMAT VERSION
HRC%HL==4		;HEADER LENGTH
HRC%EL==5		;ENTRY LENGTH EXCLUDING HEADER
;DEFINITIONS FOR DOWN-LINE LOAD FUNCTION
SEC%NL==202		;EVENT CODE FOR DOWNLINE LOAD
NL%TAR==0		;POINTER TO ASCIZ NAME OF TARGET NODE
NL%SER==1		;POINTER TO ASCIZ NMAE OF SERVER NODE
NL%SLD==2		;POINTER TO ASCIZ NAME OF SERVER LINE DESIGNATOR
NL%FIL==3		;POINTER TO NAME OF FILE LOADED
NL%RTN==4		;RETURN CODE
SUBTTL MACRO DEFINITIONS

;MACRO TO DEFINE POINTER TO ASCIZ STRING

DEFINE TXT(TEXT) <POINT 7,[ASCIZ\TEXT\]>

;MACRO TO DEFINE A TABLE ENTRY

DEFINE TB(RTN,TXT)
<	[ASCIZ/TXT/] ,, RTN
>

;MACROS TO SET THE DEFAULTS IN COMMAND STRINGS

DEFINE AZPTR(STRING,ARG) <
IFNB <STRING>,<
	HRROI	T1,[ASCIZ/STRING/]
	MOVEM	T1,GJFBLK+.GJ'ARG>>

DEFINE DEFFIL(FLAGS,DEVICE,DIRECT,FILNAM,EXTENS) <
	CALL	CLRGJF		;CLEAR GTJFN BUFFER
	MOVX	T1,FLAGS	;SET FLAGS
	MOVEM	T1,GJFBLK+.GJGEN
	AZPTR	DEVICE,DEV
	AZPTR	DIRECT,DIR
	AZPTR	FILNAM,NAM
	AZPTR	EXTENS,EXT
>

;ERROR MACROS

DEFINE BADCMD(ERRCOD,INSTR)<
IFNB	<ERRCOD>,<	JRST	[MOVEI T1,ERRCOD ;PREFIX STRING TO BE TYPED
				 HRRO T1,ERRTAB(T1) ;MAKE AS POINTER
				 CALL TYPATM	 ;TYPE ERROR MESSAGE
IFNB	<INSTR>,<		 INSTR]>	 ;EXECUTE INSTRUCTION 
IFB	<INSTR>,<		 JRST .+1]>	 ;JUST RETURN INLINE
>
IFB	<ERRCOD>,<
IFB	<INSTR>,<	JFCL>	;DO NOTHING
IFNB	<INSTR>,<	INSTR>	;DO THE INSTRUCTION, NO PRINTOUT
>>


DEFINE ERRMSG(ERRCOD,INSTR)<
IFNB	<ERRCOD>,<	JRST	[MOVEI T1,ERRCOD ;PREFIX STRING TO BE TYPED
				 MOVEM T1,SYERET ;ERROR FOR SYSERR
				 HRRO T1,ERRTAB(T1) ;MAKE AS POINTER
				 CALL TYPERR	 ;TYPE ERROR MESSAGE
IFNB	<INSTR>,<		 INSTR]>	 ;EXECUTE INSTRUCTION 
IFB	<INSTR>,<		 JRST .+1]>	 ;JUST RETURN INLINE
>
IFB	<ERRCOD>,<
IFB	<INSTR>,<	JFCL>	;DO NOTHING
IFNB	<INSTR>,<	INSTR>	;DO THE INSTRUCTION, NO PRINTOUT
>>
SUBTTL	COMMUNICATIONS PROTOCOL DEFINITIONS

MAXNOD==^D4			;MAXIMUM NUMBER OF NODES DNLOAD CAN HANDLE
MAXBSZ==1000			;MAXIMUM MEMORY IMAGE SIZE IN .BIN OR .SYS FILE
MEMSIZ==^D28			;28 PAGES
BPWRD==4			;NUMBER OF PDP-11 8-BIT BYTES PER KL20 WORD
BINHDR==6			;SIZE OF HEADER IN .BIN FILES
BTSIZ==10			;SIZE OF BOOT JSYS ARGUMENT BLOCK
PRISIZ==1000			;MAXIMUM SIZE IN BYTES TO PRIMARY (ROM) LOADER
SECSIZ==374			;MAXIMUM SIZE IN BYTES TO SECONDARY LOADER
TERSIZ==374			;MAXIMUM SIZE IN BYTES TO TERTIARY LOADER
DMPSIZ==SECSIZ_<-4>		;NEEDS SECSIZ A MULTIPLE OF FOUR
.VNDDC==2			;PROTOCOL VERSION FOR DDCMP
.BTSLS==24			;SET LINE SERVICE FUNCTION
.BTLEN==2			;!!;
.BTRDD==22			;!!;
.DCPL==1			;DDCMP LINE
NTRIES==6			;# TIMES TO RETRY SENDING MOP MSGS
MAXBYT==274			;MAXIMUM DATA LENGTH OF DDCMP MESSAGES


; MOP LOAD DEVICES AND CORRESPONDING CODES
;	ALSO DEVICE CODES FOR NICE PROTOCOL

	RADIX 5+5

.DTP11==0			;DP11
.DTU11==2			;DU11
.DTL1E==4			;DL11E
.DTQ11==6			;DQ11
.DTA11==8			;DA11A
.DTDUP==10			;DUP11
.DTDMC==12			;DMC11
.DTDLV==14			;DLV11
.DTL1A==16			;DL11A
.DTDMP==18			;DMP11 (FORMERLY KL8J)
.DTDTE==16			;DTE-20 ;NOTE...BUG IN LOADER DTEMPN REQUIRES THIS

.DTDV1==22			;DV11
.DTKDP==28			;KMC-DUP
.DTKDZ==30			;KMC-DZ

; MOP FUNCTION CODES

	RADIX 5+5

.MPLDT==0			;MEMORY LOAD WITH TRANSFER ADDRESS
.MPLOD==2			;MEMORY LOAD WITHOUT TRANSFER ADDRESS
.MPRQD==4			;REQUEST MEMORY DUMP (OR EXAMINE DATA)
.MPMOP==6			;ENTER MOP MODE
.MPRQP==8			;REQUEST PROGRAM
.MPRQL==10			;REQUEST MEMORY LOAD (ACK PREVIOUS .MPLOD)
	.MPACK==0		;ACKNOWLEDGE LAST LOAD, REQUEST NEXT
	.MPNAK==1		;ERROR ON PREVIOUS LOAD
.MPMMR==12			;MOP MODE RUNNING
	MP%DMP==2		;REMOTE SUPPORTS DUMP
.MPMDD==14			;MEMORY DUMP DATA
.MPDAP==16			; REMOTE-11	DAP MESSAGE ENVELOPE
.MPASC==18			; REMOTE-11	ENTER ASCII TELETYPE MODE
.MPREX==20			;REQUEST TO EXAMINE DATA BY NAME
.MPCLR==22			;CLEAR DATA BY NAME
.MPTST==24			;LOOPBACK TEST
.MPDAT==26			;EXAMINED DATA BY NAME


; MOP PROGRAM TYPE DEFINITIONS

.PTSLD==0			;SECONDARY LOADER
.PTTLD==1			;TERTIARY LOADER
.PTOPS==2			;OPERATING SYSTEM (PRIMARY LOAD FILE)
.PTSDM==3			;SECONDARY DUMP FILE
.PTTDM==4			;TERTIARY DUMP FILE


	RADIX 8
; RECORD BLOCK TABLE ENTRY DEFINITIONS

DEFSTR (RBJFN,RBLOCK+1,17,18)		;JFN OF FILE BEING INPUT
DEFSTR (RBFTYP,RBLOCK+1,35,9)		;FILE TYPE:
	.FTLDA==1		; LDA (ABSOLUTE BINARY) FORMAT
	.FTTSK==2		; TASK-IMAGE FORMAT
	.FTDMP==3		; DUMP FORMAT (BINARY MEMORY IMAGE)
DEFSTR	(RBPTYP,RBLOCK+1,26,9)		;PROGRAM TYPE TO BE LOADED
DEFSTR (RBBYT,RBLOCK+2,35,36)		;NUMBER OF NEXT BYTE TO READ (0-3)
DEFSTR (RBPTR,RBLOCK+3,35,36)		;POINTER TO DATA FOR THIS RECORD
DEFSTR	(RBOPTR,RBLOCK+4,35,36)		;POINTER SAVE AREA
DEFSTR (RBDAT,RBLOCK+5,35,36)		;CURRENT DATA WORD FROM INPUT FILE
DEFSTR (RBFCT,RBLOCK+6,17,18)		;COUNT OF REMAINING BYTES IN FILE
DEFSTR (RBCNT,RBLOCK+6,35,18)		;NUMBER OF BYTES IN CURRENT RECORD
DEFSTR (RBNAD,RBLOCK+7,35,36)		;BASE ADDRESS OF CURRENT RECORD
DEFSTR (RBCAD,RBLOCK+10,35,36)		;CURRENT BASE ADDRESS
DEFSTR (RBXAD,RBLOCK+11,35,36)		;TRANSFER ADDRESS FOR THIS LOAD

.RBDAT==12			;OFFSET TO DATA AREA IN RECORD BLOCK
RCTSIZ==12			;SIZE OF NON-DATA ENTRIES IN THE RECORD TABLE


; TASK-IMAGE FILE LABEL BLOCK DEFINITIONS FOR RSX-11M RELEASE 3

L$BSA==	10			;BASE ADDRESS OF TASK IMAGE
L$BLDZ==16			;LOAD SIZE IN 32. WORD BLOCKS
L$BFLG==30			;FLAGS WORD:
	TS$NHD==1B<35-14>	; BIT14- TASK HAS NO HEADER
L$BXFR==350			;TRANSFER ADDRESS
L$BHRB==356			;HEADER (OR TASK IMAGE) RELATIVE BLOCK
SECFIL:	-1,,[ASCIZ\SYS:SECDMC.SYS\] ;SECONDARY BOOT FOR LOADING DN200'S
	-1,,[ASCIZ\SYS:DTEMPN.BIN\] ;SECONDARY BOOT FOR LOADING DTE'S

TERFIL:	-1,,[ASCIZ\SYS:TERDMC.SYS\] ;TERIARY FOR DN200'S
	Z				;SAME FOR DTE'S

OPSFIL:	BLOCK	2			;SAVE OPERATING SYSTEM FILE JFN HERE

SECDMP:	-1,,[ASCIZ\sys:DMPBOT.BIN\] ;SECONDARY BOOT FOR DUMPING DN200'S
	Z
SUBTTL	COMMAND PARSER AND DISPATCH

START:	RESET			;RESET THE UNIVERSE
	MOVE P,[IOWD PDLEN,PDL]	;SET UP STACK
	MOVEI	T1,.FHSLF	;CURRENT FORK HANDLE
	RPCAP			;GET PROCESSES PRIV'S
	TXNN	T3,SC%WHL	;MUST HAVE WHEEL OR
	TXNE	T3,SC%OPR	;OR OPERATOR PRIV'S ENABLED
	JRST	STRT0		;USER HAS RIGHT PRIVILEGES ENABLED
	ERRMSG(.ERR50,HALTF)	;GIVE ERROR AND HALT
STRT0:	SETZM TAKFLG		;MARK THAT TAKE FILE NOT BEING PROCESSED
	HRROI T1,PROMPT		;GET POINTER TO PROMPT STRING
	MOVEM T1,CMDBLK+.CMRTY	;PUT RE-TYPE PROMPT POINTER IN STATE BLOCK
	HRROI T1,BUFFER		;GET POINTER TO INPUT TEXT BUFFER
	MOVEM T1,CMDBLK+.CMPTR	;SAVE POINTER TO COMMAND STRING
	MOVEM T1,CMDBLK+.CMBFP	;SAVE POINTER TO START-OF-BUFFER
	MOVE T1,[.PRIIN,,.PRIOU] ;GET PRIMARY INPUT,, OUTPUT JFN'S
	MOVEM T1,CMDBLK+.CMIOJ	;SAVE PRIMARY JFN'S
	MOVEI T1,PARSE1		;GET RE-PARSE ADDRESS
	MOVEM T1,CMDBLK+.CMFLG	;SAVE RE-PARSE ADDRESS
	SETZM CMDBLK+.CMINC	;INITIALIZE # OF CHARACTERS AFTER POINTER
	MOVEI T1,BUFSIZ*NCHPW	;GET # OF CHARACTERS IN BUFFER AREA
	MOVEM T1,CMDBLK+.CMCNT	;SAVE INITIAL # OF FREE CHARACTER POSITIONS
	HRROI T1,ATMBFR		;GET POINTER TO ATOM BUFFER
	MOVEM T1,CMDBLK+.CMABP	;SAVE POINTER TO LAST ATOM INPUT
	MOVEI T1,ATMSIZ*NCHPW	;GET # OF CHARACTERS IN ATOM BUFFER
	MOVEM T1,CMDBLK+.CMABC	;SAVE COUNT OF SPACE LEFT IN ATOM BUFFER
PARSE:	HRROI T1,PROMPT		;GET POINTER TO PROGRAM'S PROMPT STRING
	CALL CMDINI		;OUTPUT THE PROMPT

PARSE1:	MOVE P,[IOWD PDLEN,PDL]	;SET UP STACK AGAIN
	SETOM T1		;INDICATE ALL JFN'S SHOULD BE RELEASED
	RLJFN			;RELEASE ALL JFN'S
	 JSERR			;UNEXPECTED ERROR
	CALL CLRGJF		;GO CLEAR GTJFN BLOCK

	MOVEI T1,GJFBLK		;GET ADDRESS OF GTJFN BLOCK
	MOVEM T1,CMDBLK+.CMGJB	;STORE POINTER TO GTJFN BLOCK
	MOVEI T1,CMDBLK		;GET POINTER TO COMMAND STATE BLOCK
	MOVEI T2,[FLDDB. (.CMKEY,,CMDTAB)] ;GET FUNCTION BLOCK
	COMND			;DO INITIAL PARSE, DEFAULT IS LOAD
	 ERJMP CMDERR		;ERROR, GO CHECK FOR EOF ON TAKE FILE
	TXNN T1,CM%NOP		;VALID COMMAND ENTERED ?
	JRST PARSE5		;YES, GO DISPATCH TO PROCESSING ROUTINE
	 BADCMD(.ERR0)		;ILLEGAL COMMAND
	JRST PARSE		;GO TRY TO GET A COMMAND AGAIN

PARSE5:	HRRZ T1,(T2)		;GET DISPATCH ADDRESS
	CALL (T1)		;PERFORM REQUESTED FUNCTION
	 JFCL			;ERRORS ALREADY HANDLED
	JRST PARSE		;GO PARSE NEXT COMMAND
SUBTTL LOAD/DLOAD COMMANDS

.LOAD:	TDZA T1,T1		;NOTE LOAD RATHER THAN DIAGNOSTIC LOAD
.DLOAD:	SETOM T1		;NOTE DIAGNOSTIC LOAD REQUESTED

	MOVEM T1,LDFLG		;SAVE FLAG INDICATING WHETHER LOAD OR DLOAD
	HRROI	T2,[ASCIZ\DEVICE\]
	CALL	SKPNOI		;PROMPT FOR DEVICE TO LOAD
	 BADCMD(.ERR2,RET)	;COMMAND ERROR
	MOVEI	T1,CMDBLK
	MOVEI	T2,[FLDDB. (.CMKEY,,LDDVTB,,<DTE>)]
	COMND			;PARSE DEVICE TO BE LOADED
	 ERJMP	CMDERR
	TXNE	T1,CM%NOP	;VALID COMMAND ENTERED?
	 BADCMD(.ERR1,RET)	;NOT A CORRECT TARGET FOR BOOTING.
	HRRZ	T1,(T2)		;DISPATCH ADDRESS FOR THIS DEVICE
	JRST	(T1)		;CALL ROUTINE
SUBTTL START,STOP PROTOCOL COMMANDS

.START:	TDZA	T1,T1		;start a protocol
.STOP:	SETO	T1,		;stop protocol
	MOVEM	T1,PROFLG
	JUMPN	T1,.STP
	CALL	GETPRO		;get the protocol type
	RET

.STP:	HRROI	T2,[ASCIZ\protocol on line/DTE\]
	CALL	SKPNOI		;prompt for dte number
	 BADCMD(.ERR2,RET)	;command error
	MOVEI T1,CMDBLK		;get address of command state block
	MOVEI T2,[FLDDB. (.CMNUM,,^D8)]
	COMND			;parse a dte20 number
	 ERJMP CMDERR		;go test for eof on failure
	TXNE T1,CM%NOP		;parsed dte20 number ok ?
	 BADCMD(.ERR7,RET)	;bad device number
	MOVEM	T2,LDDEV	;save dte #
	CALL ENDCOM		;parse end of command
	 ERRMSG(.ERR21,RET)
	SKIPE	PROFLG
	JRST	STPPRO		;go stop protocol
	SETZM	LDFLG		;don't let him think a DLOAD was done
	JRST	STRPRO		;go start protocol

GETPRO:	MOVEI	T1,CMDBLK	;get the protocol to start 
	MOVEI	T2,[FLDDB. (.CMKEY,,PRVRTB,,<DN60>)] ;default to DN60 protocol
	COMND			;parse protocol version
	 ERJMP	CMDERR
	TXNE	T1,CM%NOP	;valid command entered?
	 BADCMD(.ERR51,RET)	;loser
	HRRZ	T1,(T2)
	JRST	(T1)		;dispatch to protocol name

PRD22:	SETOM	LDTYP		;DN22 protocol(DDCMP)
	RETSKP

PRMCB:	MOVEI	T1,.VNMCB	;MCB protocol
	JRST	SETPRO

PRD60:	SKIPA	T1,[.VND60]	;DN60 protocol

PR20F:	MOVEI	T1,.VN20F	;RSX20F protocol

SETPRO:	MOVEM	T1,PTYPE	;set the protocol
	RETSKP
SUBTTL LOAD DTE/DMC COMMANDS

LDPDP:	SETOM LDTPDP		;**PDP** flag as load of DECnet node
	SKIPA			;**PDP** and as flavor of DN22 load
				;**PDP**
LDDTE:	TDZA	T1,T1		;NOTE THIS LOAD OF A DTE
LDDMC:	SETOM	T1		;NOTE THIS IS LOAD OF A DN22
	MOVEM	T1,LDTYP	;SAVE FOR LATER
	HRROI	T2,[ASCIZ\ON LINE/DTE\] ;NOISE
	CALL	SKPNOI
	 BADCMD(.ERR2,RET)
	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[FLDDB. (.CMNUM,,^D8)]
	COMND			;PARSE A DTE20 NUMBER
	 ERJMP CMDERR		;GO TEST FOR EOF ON FAILURE
	TXNE T1,CM%NOP		;PARSED DTE20 NUMBER OK ?
	 BADCMD(.ERR7,RET)		;BAD DEVICE NUMBER

	MOVEM	T2,LDDEV	;SAVE THE DEVICE #
	MOVE	T1,LDTYP	;GET TYPE OF LOAD DEVICE
	CALL	CHKLDV		;CHECK THE LOAD DEVICE
	 BADCMD(.ERR7,RET)

; PARSE FILESPEC TO LOAD

	HRROI T2,[ASCIZ/FROM/]	;GET POINTER TO GUIDE WORDS
	CALL SKPNOI		;PARSE NOISE WORDS
 	 BADCMD(.ERR2,RET)	;FAILED
	DEFFIL	GJ%OLD,DSK:,,,BIN ;SET DEFAULTS FOR LOAD COMMAND FILE
	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[FLDDB. (.CMFIL)]
	COMND			;PARSE INPUT FILESPEC
	 ERJMP CMDERR		;IF FAILED, GO CHECK FOR END OF FILE
	TXNE T1,CM%NOP		;FILESPEC PARSED OK ?
	 BADCMD(.ERR17,RET)	 ;BAD FILE SPEC.
	MOVEM	T2,LDFIL	;SAVE JFN TO FILE SPEC
	HRROI	T1,SYEDAT+12	;WHERE TO PUT FILE NAME FOR SYSERR
	MOVX	T3,<FLD(.JSAOF,JS%DEV)>
	JFNS
	MOVEI	T3,"<:"		;INSERT DEVICE/DIRECTORY DELIMITER
	IDPB	T3,T1		;DEPOSIT IN NAME STRING
	LSH	T3,-7		;POSITION FOR <
	IDPB	T3,T1		;DEPOSIT <
	MOVX	T3,<FLD(.JSAOF,JS%DIR)> ;GET DIRECTORY NAME
	JFNS
	MOVEI	T3,">"		;DIRECTORY/FILE NAME DELIMITER
	IDPB	T3,T1		;PUT IN NAME STRING
	MOVX	T3,<FLD(.JSAOF,JS%NAM)>
	JFNS			;GET THE  FILE NAME
	MOVEI	T3,"."
	IDPB	T3,T1		;FILE NAME/EXTENSION DELIMITER
	MOVX	T3,<FLD(.JSAOF,JS%TYP)>
	JFNS			;GET THE EXTENSION
	MOVEI	T3,"."
	IDPB	T3,T1		;PUT IN FILE EXTENSION/GENERATION DELIMITER
	MOVX	T3,<FLD(.JSAOF,JS%GEN)>
	JFNS			;GET THE GENERATION NUMBER
	HRRZ	T3,T1		;FINAL VALUE OF POINTER
	SUBI	T3,SYEDAT+12	;#FULL WORDS IN FILE SPEC.
	IMULI	T3,5		;#CHARACTERS IN FULL WORDS
	ROT	T1,6
	ANDI	T1,77		;NUMBER OF BITS INTO WORD
	IDIVI	T1,7		;DIVIDE BY BITS PER CHARACTER
	SUBI	T1,5
	SUB	T3,T1		;TOTAL NUMBER OF CHACTERS IN FILE SPEC
	MOVNS	T3		;NEED NEGATIVE
	HRLM	T3,SYFNAM	;STORE IN SYSERR BLOCK
	MOVE	T1,LDDEV	;LINE NUMBER OF LOAD
	ADDI	T1,60		;MAKE ASCII
	DPB	T1,[POINT 7,SYEDEV+1,13] ;STORE IN SYSERR BLOCK
	MOVE	P1,LDTYP	;DEVICE BEING LOADED
	CALL PRSLSN		;GO PARSE THE LISTENING DEVICE
	 RET			;ERRORS ALREADY HANDLED
	SETZM	SYERET	;ZERO RETURN CODE FOR SYSERR
	CALL	LOADIT		;GO DO THE LOAD
	 JFCL			;ERROR HANDLING ALREADY DONE
	CALL SYERPT		;REPORT TO SYSERR
	RET			;RETURN
LOADIT:	MOVE	T2,LDFIL	;GET THE OPS JFN
	MOVEM	T2,OPSFIL+1(P1)	;SAVE JFN TO OPERATING SYSTEM FILE.
	MOVE	T1,SECFIL+1(P1) ;POINTER TO FILE SPEC FOR SECONDARY
	CALL	OPNIFL		;OPEN THE FILE
	 ERRMSG(.ERR11,RET)		 ;OPEN ERROR.
	STOR	T1,RBJFN	;SAVE JFN OF FILE BEING LOADED
	MOVEI	T2,.PTSLD	;THIS IS LOAD OF SECONDARY BOOTSTRAP
	STOR	T2,RBPTYP	;SO OTHERS CAN SEE THIS
	MOVEI	T2,PRISIZ	;MAXIMUM SIZE OF BINARY IMAGE TO ROM
	MOVEM	T2,MAXMEM	;STORE FOR READ ROUTINE
	CALL	RQLOD		;GO DO THE LOADING
	 ERRMSG(,CALLRET CLSFIL)	;ERROR, CLOSE FILE AND RETURN
	CALL	CLSFIL		;CLOSE THE SECONDARY BOOT FILE
	CALL	CHKRQP		;CHECK THE ANSWER FROM SECONDARY BOOT
	 ERRMSG(.ERR16,RET)
	LOAD	T1,RBPTYP	;GET PROGRAM TYPE THE SECONDARY WANTS 
	CAIE	T1,.PTTLD	;IS IT THE TERTIARY LOADER?
	JRST	LODOPS		;NO, GO LOAD THE OPERATING SYSTEM
	MOVE	T1,TERFIL+1(P1) ;POINTER TO FILE SPEC FOR TERTIARY BOOT
	CALL	OPNIFL		;OPEN THE FILE
	 ERRMSG(.ERR27,RET)
	STOR	T1,RBJFN	;SAVE THE JFN
	MOVEI	T2,SECSIZ	;MAXIMUM SIZE OF BINARY IMAGE TO SECONDARY
	MOVEM	T2,MAXMEM	;FOR THE FILE READ ROUTINE
	CALL	RQLOD
	 ERRMSG(,CALLRET CLSFIL)	;ALL ERRORS HAVE ALREADY BEEN PROCESSED.
	CALL CLSFIL		;CLOSE THE TERTIARY LOADER
LODOPS:
	LOAD	T1,RBPTYP	;GET PROGRAM TYPE TO BE LOADED
	CAIE	T1,.PTOPS	;SHOULD WANT THE OPERATING SYSTEM HERE
	 ERRMSG(.ERR45,RET)		 ;NOT SO!
	MOVE	T1,OPSFIL+1(P1)	;GET THE JFN FOR THE OPERATING SYSTEM
	CALL	OPSOPN		;OPEN IT. JFN EXISTS ALREADY.
	 ERRMSG(.ERR30,RET)
	STOR	T1,RBJFN	;SAVE THE JFN
	MOVEI	T2,TERSIZ	;MAXIMUM SIZE OF BINARY IMAGE TO TERTIARY LDR
	MOVEM	T2,MAXMEM	;
	CALL	INIDDC		;INITIALIZE LINE AS DDCMP LINE
	 ERRMSG(.ERR43,CALLRET CLSFIL)		;SHOULD NEVER HAPPEN
	LOAD	T1,RBJFN	;GET THE JFN AGAIN
	CALL	RQLOD
	 ERRMSG(,CALLRET CLSFIL)	;ERROR, CLOSE FILE AND RETURN
	CALL	CLSFIL		;CLOSE FILE
;	SKIPE	LDFLG		;WAS A DLOAD ISSUED?
;	JRST	DGNCNV		;YES, GO START CONVERSATION WITH DIAGNOSTIC
	SKIPE LDTPDP		;**PDP** was a LOAD PDP issued ?
	JRST ELDPDP		;**PDP** Yes, reset line then exit.

STRPRO:	CALL	INIPRO		;START UP THE LINE
	 ERRMSG(.ERR43,RET)		;FAILED
	RETSKP			;LOAD NOW COMPLETE
ELDPDP:	CALL LDKMC		;**PDP** Reload KMC11 (There must be
				;**PDP**   a better way to Init the KMC ...)
				;**PDP**
	CALL CLRBOT		;**PDP**
	MOVEI T2,BTARG		;**PDP**
	MOVE T1,LDDEV		;**PDP**
	MOVEM T1,.BTDTE(T2)	;**PDP**
.BTNSP=0			;**PDP**
	MOVEI T1,.BTNSP		;**PDP** Set line service to be NSP
	MOVEM T1,.BTCOD(T2)	;**PDP**
	MOVEI T1,.BTSLS		;**PDP** Set line service function code
	BOOT			;**PDP**
	 ERJMP [ERRMSG(.ERR43,RET)]	;**PDP**
	CALL CLRBOT		;**PDP** prepare to start line.. clear arg block
	MOVEI T2,BTARG		;**PDP**
	MOVE T1,LDDEV		;**PDP** unit to load
	MOVEM T1,.BTDTE(T2)	;**PDP** put into arg blk
	MOVE T1,.VNDDC		;**PDP** protocol to use - DDCMP
	MOVEM T1,.BTPRV(T2)	;**PDP**
	MOVEI T1,.BTIPR		;**PDP** init protocol
	BOOT			;**PDP**
	 ERJMP [ERRMSG(.ERR43,RET)]	;**PDP**
	SETZM LDTPDP		;**PDP** Else LOAD DN22 & LOAD KMC
				;**PDP**   will be broken
	RETSKP			;**PDP**
				;**PDP**
;RQLOD - ROUTINE TO DO THE LOADING OF A SATELLITE COMPUTER.
;
;ACCEPTS IN T1/	JFN OF FILE CONTAINING PROGRAM TO BE BOOTED.
;		CALL RQLOD
;
;RETURNS +1	 ERROR RETURN,
;        +2	SUCCESS, LOAD COMPLETE

RQLOD:
	CALL FILTYP		;DETERMINE THE TYPE OF FILE TO LOAD
	 ERRMSG(.ERR32,RET)
	STOR	T2,RBFTYP	;STORE FILE TYPE BEING LOADED
	MOVEI	T1,777777	;SET UP INITIAL LOAD ADDRESS TO DUMMY
	STOR	T1,RBCAD	;STORE IT
	MOVEI	T1,0
	MOVEM	T1,LDNUM	;START WITH LOAD ZERO.
	MOVX	T1,BPWRD	;PDP-11 BYTES PER WORD
	STOR	T1,RBBYT	;TO FORCE A READ IN INPBYT ROUTINE
	MOVEI	T4,0
	STOR	T4,RBFCT	;INITIALIZE COUNT
RQLOD0:	LOAD	T2,RBFTYP	;GET FILE TYPE FOR DISPATCHING
	CALL	@[R		;ILLEGAL
		  Z INPLDA	;BIN FORMAT
		  Z INPTSK	;SYS FORMAT
		  ](T2)
	 ERRMSG(.ERR34,RET)		;;!!;; be sure to print out filename here
	LOAD	T2,RBPTYP	;TYPE OF PROGRAM BEING LOADED
	CAIN	T2,.PTSLD	;SECONDARY LOADER.
	CALLRET	RQLSB		;YES, SECONDARY IS SPECIAL
	LOAD	T1,RBCNT	;ANY MORE BYTES TO TRANSFER?
	SKIPN	T1		;YES,
	CALLRET	RQXFER		;NO, GO SEND TRANSFER MESSAGE
	MOVEI	T1,NTRIES	;NUMBER OF TIMES TO RETRY A LOAD IMAGE
	MOVEM	T1,LDRTRY	;SAVE FOR CHKMOP ROUTINE
	CALL	MAKMPL		;MAKE A LOAD-WITHOUT-TRANSFER MOP MSG
	 ERRMSG(.ERR23,RET)
RQAGN:	CALL MOPSND		;SEND OUT THE MOP MSG
	 ERRMSG(.ERR24,RET)
	CALL MOPRCV		;RECEIVE THE ANSWER FROM LOADER
	 JRST	[SKIPG	LDRTRY	;RETRY COUNT EXHAUSTED?
		 ERRMSG(.ERR25,RET) ;YES, RETURN ERROR
		 SOS	LDRTRY	;DECREMENT RETRY COUNT AND TRY AGAIN
		JRST	RQAGN]
	CALL	CHKMOP		;CHECK THE VALIDITY OF ANSWER
	 ERRMSG(.ERR26,RET)
	JRST	RQLOD0		;GO TRANSFER SOME MORE
RQXFER:
	MOVEI	T1,NTRIES	;NUMBER OF ATTEMPTS TO MAKE
	MOVEM	T1,LDRTRY
	CALL	MAKMLX		;MAKE A LOAD-WITH-TRANSFER MESSAGE
	 RET			;ERROR ALREADY ANNOUNCED
RQAGNX:	CALL MOPSND		;SEND OUT THE MOP MESSAGE
	 ERRMSG(.ERR24,RET)
	CALL	MOPRCV		;GO RECEIVE THE ANSWER
	 JRST	[SKIPG	LDRTRY	;RETRY COUNT EXHAUSTED?
		 ERRMSG(.ERR25,RET) ;YES, RETURN ERROR
		 SOS	LDRTRY	;DECREMENT AND TRY AGAIN
		 JRST	RQAGNX]
	LOAD	T1,RBPTYP	;GET THE PROGRAM TYPE BEING LOADED
	CAIE	T1,.PTOPS	;IS IT THE OPERATING SYSTEM?
	JRST	[CALL CHKRQP	;NO, MAKE SURE LOADER ASKING FOR ANOTHER LOAD
		  ERRMSG(.ERR26,RET)
		 RETSKP]
	CALL	CHKMOP		;CHECK IT TOO
	 ERRMSG(.ERR26,RET)
	RETSKP			;LOAD NOW COMPLETE
;ROUTINE TO LOAD A REMOTE COMPUTER UP THRU SECONDARY BOOTSTRAP.

; TERMINATE ANY PROTOCOL PREVIOUSLY RUNNING

RQLSB:	STKVAR <SECCTR,SECPTR>

	MOVE T1,LDDEV		;GET DTE20 NUMBER
	CALL TRMPRO		;GO TERMINATE THE PROTOCOL
	 RET			;FAILED
	CALL	FLUSH		;FLUSH OUT THE LINE
	 RET			;ERROR

; TRIGGER THE ROM IN THE REMOTE COMPUTER
	SKIPN	LDTYP		;DON'T TRIGGER ON A DTE
	JRST	RQLSB0		;SINCE LOAD SECONDARY FUNCTION WILL DO THIS
	MOVEI	T1,NTRIES	;NUMBER TIMES TO TRY TO TRIGGER
	MOVEM	T1,LDRTRY	;AS RETRY COUNT
TRGAGN:	CALL	CLRBOT		;CLEAR OUT THE BOOT JSYS ARG BLOCK
	MOVEI	T2,BTARG	;ADDRESS OF BOOT JSYS ARG BLOCK
	MOVE	T4,LDDEV	;GET THE DEVICE #
	MOVEM	T4,BTARG+.BTDTE	;PUT INTO ARG BLOCK
	MOVEI	T1,.BTROM	;SET UP THE FUNCTION CODE
	BOOT
	 ERJMP	[SKIPG	LDRTRY	;RETRY COUNT EXHAUSTED?
		 ERRMSG(.ERR14,RET) ;YES, RETURN ERROR
		 SOS	LDRTRY	;DECREMENT COUNT AND
		 JRST	TRGAGN]	;TRY AGAIN

;BUILD IMAGE DATA
RQLSB0:	SETZM	SECCTR		;BYTE COUNTER
	MOVEI	T3,XMPMSG	;WHERE IMAGE DATA IS TO GO
	LOAD	T4,RBCNT	;#BYTES IN IMAGE DATA
RQLSB2:	LOAD	T1,RBPTR	;POINTER TO IMAGE DATA
	MOVEM	T1,SECPTR	;SAVE POINTER
RQLSB3:	ILDB	T1,SECPTR	;GET A BYTE FROM IMAGE DATA
	LDB	T2,[POINT 2,SECCTR,35] ;INDEX INTO BYTE POINTER TABLE
	DPB	T1,SLDTAB(T2)	;DEPOSIT BYTE INTO MOPMSG
	AOS	T1,SECCTR	;INCREMENT INDEX
	CAIL	T1,1000		;TOO MANY?
	 ERRMSG(.ERR36,RET)		;YES, ERROR
	TXNN	T1,3		;CROSSED A WORD BOUNDARY?
	ADDI	T3,1		;YES, INCREMENT TO NEXT WORD
	SOJG	T4,RQLSB3	;DO MORE IF ANY

	MOVEM	T3,SECPTR	;SAVE T3
	LOAD	T2,RBFTYP	;FILE TYPE
	CALL	@[R		;ILLEGAL
		  Z INPLDA	;BIN
		  Z INPTSK	;SYS
		](T2)		;
	 ERRMSG(.ERR34,RET)
	MOVE	T3,SECPTR	;RESTORE T3
	LOAD	T4,RBCNT	;ANY MORE THERE.  NORMALLY NO.
	SKIPE	T4		;NONE
	JRST	RQLSB2		;GO DO THIS BLOCK TOO
	MOVEI	T1,NTRIES	;NUMBER OF TIMES TO TRY
	MOVEM	T1,LDRTRY

; LOAD THE SECONDARY BOOTSTRAP

AGNSB:	CALL	CLRBOT		;CLEAR OUT THE BOOT JSYS ARG BLOCK
	MOVE T4,LDDEV		;GET DTE20 NUMBER
	MOVEM T4,BTARG+.BTDTE	;SAVE DTE20 NUMBER IN JSYS ARG BLOCK
	MOVEI	T4,XMPMSG	;POINTER TO SECONDARY BOOTSTRAP FILE DATA
	MOVEM T4,BTARG+.BTSEC	;SAVE SECONDARY BOOTSTRAP DATA ADDRESS
	MOVEI T1,.BTLDS		;GET "LOAD SECONDARY" FUNCTION CODE
	MOVEI T2,BTARG		;GET ADDRESS OF ARGUMENT BLOCK
	BOOT			;LOAD THE SECONDARY BOOTSTRAP
	 ERJMP	[ERRMSG(.ERR13,RET)]
	CALL	MOPRCV		;GET RESPONSE FROM THE LOADER
	 JRST	[SKIPG	LDRTRY	;RETRY COUNT EXHAUSTED?
		 ERRMSG(.ERR15,RET) ;YES, RETURN ERROR
		 SOS	LDRTRY	;DECREMENT COUNT AND
		 JRST	AGNSB]	;TRY AGAIN
	RETSKP
	; ..
SUBTTL LOAD KMC CODE
;HERE TO LOAD THE KMC ON A 2020.  FILE CONTAINING MICROCODE IS ASSUME
;TO BE IN THE FILE SYS:COMIOP.KMC

LDKMC:
	STKVAR	<<BTLBLK,14>,<BTLPAG,2>,BTLFIL>
	MOVEI	T1,0		;ONLY ALLOW LOADING OF KDP_0
	IMULI	T1,10		;CONVERT UNIT # TO OFFSET
	ADD	T1,[3,,760540]	;THIS IS KMC11 ADDRESS
	MOVEM	T1,.BTKMC+BTLBLK ;PUT ADDRESS IN ARG BLOCK
	SKIPE LDTPDP		;**PDP** is this KMC reload for LOAD PDP11 cmd ?
	JRST LDKMCP		;**PDP** Yes, skip command parsing.
	MOVEI	T1,CMDBLK	;
	MOVEI	T2,[FLDDB. (.CMCFM)] ;ACCEPT END OF COMMAND ONLY
	COMND
	 ERJMP	CMDERR		;ERROR
	TXNE	T1,CM%NOP
	 ERRMSG(.ERR2,RET)
LDKMCP:				;**PDP**
	HRROI	T2,[ASCIZ\SYS:COMIOP.KMC\] ;FILE NAME FOR uCODE.
	MOVX T1,GJ%OLD!GJ%SHT	;FILE FOR INPUT USE, SHORT CALL
	GTJFN			;GET A JFN FOR INPUT FILE
	 ERRMSG(.ERR3,RET)
	HRRZM T1,BTLFIL		;SAVE JFN
	MOVE T2,[070000,,OF%RD]	;7-BIT BYTES, READ ACCESS ONLY
	OPENF			;OPEN THE FILE
	 ERRMSG(.ERR3,RET)
	MOVEI	T2,DRAMPG	;PAGE FOR DRAM
	MOVEM T2,BTLPAG		;SAVE ADR OF FIRST WORD IN PAGE
	SETZM (T2)		;CLEAR FIRST WORD IN PAGE
	HRLI T1,(T2)		;MAKE BLT POINTER
	HRRI T1,1(T2)
	BLT T1,777(T2)		;CLEAR THE PAGE
	MOVEI	T2,CRAMPG	;PAGE FOR CRAM
	MOVEM T2,1+BTLPAG	;SAVE ADR OF FIRST WORD IN PAGE
	SETZM (T2)		;CLEAR FIRST WORD IN PAGE
	HRLI T1,(T2)		;MAKE BLT POINTER
	HRRI T1,1(T2)
	BLT T1,777(T2)		;CLEAR THE PAGE
	SETZM .BTKSA+BTLBLK	;NO STARTING ADDRESS YET
	MOVE T1,BTLFIL		;GET FILE JFN
LOAKD1:	BIN			;GET NEXT BYTE
	ERJMP LOAKD3		;IN CASE EOF
	CAIN T2,"C"		;IS THIS CRAM DATA ?
	JRST LDKMC1		;LOADING THE CRAM
	CAIN T2,"D"		;IS THIS DRAM DATA ?
	JRST LDKMD1		;LOADING THE DRAM
	CAIE T2,15		;IS THIS A CARRIAGE RETURN ?
	CAIN T2,12		;OR A LINE FEED ?
	JRST LOAKD1		;YES SO LOOK FOR COMMAND TYPE
	CAIN T2,14		;OR A FORM FEED ?
	JRST LOAKD1		;YES SO LOOK FOR TYPE OF COMMAND
	CAIE T2,";"		;IS THIS A COMMENT LINE ?
	JRST LOAKMX		;Bad data in load file
LOAKD2:	BIN			;GET NEXT CHARACTER
	ERJMP LOAKD3
	CAIE T2,12		;IS THIS A LINE FEED ?
	CAIN T2,14		;OR A FORM FEED
	JRST LOAKD1		;YES SO LOOK FOR COMMAND CHARACTER
	JRST LOAKD2		;KEEP FLUSHING LINE

LOAKD3:	SETZM .BTKER+BTLBLK	;INITIALIZE FLAGS
	MOVE T1,BTLPAG		;GET ADR OF PAGE
	HRLI T1,(POINT 16,)	;MAKE INTO BYTE POINTER
	MOVEM T1,.BTKCP+BTLBLK
	MOVEI T1,2000		;COUNT FOR CRAM
	MOVEM T1,.BTKCC+BTLBLK
	MOVE T1,1+BTLPAG	;GET ADR OF PAGE
	HRLI T1,(POINT 8,)	;MAKE INTO BYTE POINTER
	MOVEM T1,.BTKDP+BTLBLK
	MOVEI T1,2000		;COUNT FOR DRAM
	MOVEM T1,.BTKDC+BTLBLK
	SETZM .BTKRC+BTLBLK	;NOT LOADING REGISTERS
	MOVEI T1,.BTKML		;WANT TO LOAD THE KMC11
	MOVEI T2,BTLBLK		;POINT TO BLOCK
	BOOT
	 ERJMP [MOVEI T4,.ERR4	;JSYS error
		JRST LOAKD6 ]
	SETZ T4,		;LOAD WON
LOAKD6:	MOVE T1,BTLFIL		;GET FILE JFN
	RLJFN			;RELEASE THE JFN
	 ERJMP .+1
	SKIPE T1,T4		;WAS THERE AN ERROR ?
	 ERRMSG(<(T4)>,RET)
	RET
;HERE TO READ CRAM DATA TO LOAD IN KMC11
LDKMC1:	MOVE T2,BTLPAG		;GET ADR OF PAGE
	HRLI T2,(POINT 16,)	;MAKE POINTER TO AREA
	CALL LDKMCX		;GET THE DATA
	 JRST LOAKMX		;LOST
	SKIPE T2		;WAS THIS A STARTING ADDRESS ?
	MOVEM T2,.BTKSA+BTLBLK	;SAVE STARTING ADDRESS
	JRST LOAKD1		;ON TO NEXT LINE

;HERE TO READ DRAM DATA TO LOAD IN KMC11
LDKMD1:	MOVE T2,1+BTLPAG	;GET ADR OF PAGE
	HRLI T2,(POINT 8,)	;MAKE POINTER TO DATA
	CALL LDKMCX		;GET THE DATA
	 JRST LOAKMX		;LOST
	JUMPE T2,LOAKD1		;ON TO NEXT LINE
LOAKMX:	MOVEI T4,.ERR5		;Bad data in load file
	JRST LOAKD6

LDKMCX:				;SAVE THE Q REGISTERS
	MOVE Q1,T2		;SAVE POINTER
	BIN			;GET SPACE
	ERJMP R			;LOSE ON EOF
	SETZ T4,		;ACCUMULATE THE CHECKSUM HERE
	CAIN T2,40		;IS THIS A SPACE ?
	CALL LOAKMN		;GET WORD COUNT FROM THE FILE
	 RET			;LOST
	SKIPL Q2,T2		;SAVE COUNT
	CALL LOAKMN		;GET ADDRESS FROM THE FILE
	 RET			;LOST
	SKIPG T3,Q2		;COPY COUNT
	JRST [	MOVEM T2,Q1	;SAVE STARTING ADDRESS
		CALL LOAKMN	;GET THE CHECKSUM
		 RET		;LOST
		MOVE T2,Q1	;PICK UP STARTING ADDRESS
		HRLI T2,(BT%KSA) ;THIS IS A STARTING ADDRESS
		JUMPE T4,RSKP	;IF CHECKSUM OK WE WON
		RET ]
	ADDI T3,T2
	CAILE T3,2000		;IS THIS REASONABLE ?
	RET
	CAIA
	IBP Q1			;ADVANCE BYTE POINTER
	SOJGE T2,.-1		;LOOP TILL HIT RIGHT BYTE
	CALL LOAKMN		;GET NEXT DATA BYTE
	 RET
	IDPB T2,Q1		;PUT BYTE INTO DATA
	SOJG Q2,.-3
	CALL LOAKMN		;GET THE CHECKSUM
	 RET
	SETZ T2,
	JUMPE T4,RSKP		;IF CHKSUM IS 0 WE WON
	RET
;HERE TO GET A NUMBER FROM A LOAD FILE
LOAKMN:	JSP	CX,SAVQ			;SAVE THE Q REGISTERS
	SETZB Q2,Q3		;BUILD NUMBER HERE
LOAKM2:	BIN			;GET 
	ERJMP R
	CAIL T2,75		;IS THIS ENCODED DATA ?
	CAILE T2,174
	JRST [	IMULI Q3,6	;MAKE HOW MUCH TO ROTATE BACK
		ROTC Q1,(Q3)
		MOVE T2,Q2	;COPY DATA
		ADD T4,Q2	;INCLUDE IN CHECKSUM
		ANDI T4,177777	;STRIP OVERFLOW
		RETSKP ]
	ANDI T2,77		;STRIP EXTRA BITS
	ADDI Q2,(T2)		;INCLUDE IN NUMBER
	ROTC Q1,-6		;POSITION OLD BITS
	AOJA Q3,LOAKM2		;GET NEXT CHARACTER
	RET
; HERE TO PARSE END OF COMMAND OR LINE SPECIFICATION

PRSLSN:
	MOVX	T1,<.DVDES+.DVNUL,,-1> ;DESIGNATOR FOR NULL DEVICE
	MOVEM	T1,LDLIN	;AS DEFAULT
	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,LSTCHN		;GET ADR OF CHAIN OF FDB'S FOR LAST FIELD
	COMND			;PARSE NEXT FIELD
	 ERJMP CMDERR		;GO TEST FOR EOF IF FAILED
	TXNE T1,CM%NOP		;PARSED ONE OF THE FIELDS OK ?
	 ERRMSG(.ERR20,RET)
	LOAD T4,CM%FNC,(T3)	;GET FUNCTION ACTUALLY PARSED
	CAIN T4,.CMCFM		;END OF COMMAND ?
	JRST LOD038		;YES, GO PROCESS COMMAND AS IS
	CAIN T4,.CMNOI		;PARSED NOISE FIELD ?
	JRST LOD036		;YES, GO PARSE KEYWORD OR CONFIRMATION NEXT
	MOVEM T2,LDLIN		;SAVE DESIGNATOR OF LINE TO LISTEN ON
	CALL ENDCOM		;PARSE END OF COMMAND
	 ERRMSG(.ERR21,RET)
	JRST LOD038		;DONE, GO PROCESS COMMAND

; HERE TO PARSE REST OF LINE AFTER (LISTENING ON)

LOD036:	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[FLDDB. (.CMDEV,,,,,[FLDDB. (.CMCFM)])]
	COMND			;PARSE KEYWORD OF END OF COMMAND
	 ERJMP CMDERR		;FAILED, GO TEST FOR EOF
	TXNE T1,CM%NOP		;PARSED FIELD OK ?
	 ERRMSG(.ERR20,RET)
	LOAD T4,CM%FNC,(T3)	;GET FUNCTION CODE PARSED
	CAIE T4,.CMDEV		;PARSED A DEVICE ?
	JRST LOD038		;NO, PARSED CONFIRMATION. GO PROCESS COMMAND.
	MOVEM T2,LDLIN		;SAVE DESIGNATOR
	CALL ENDCOM		;PARSE END OF COMMAND
	 ERRMSG(.ERR21,RET)

; SET UP THE LINE TO LISTEN ON IF DEFAULTED

LOD038:	MOVE T1,LDLIN		;GET DESIGNATOR FOR LISTENING LINE
	DVCHR			;GET DEVICE CHARACTERISTICS
	LOAD T4,DV%TYP,T2	;GET DEVICE TYPE
	CAIE T4,.DVNUL		;NULL IS OK, AS IS
	CAIN T4,.DVTTY		; A TERMINAL LINE ?
	JRST LOD039		;YES, GO PROCESS LOAD COMMAND
	 ERRMSG(.ERR22,RET)
	; ..
	; ..

; SET UP TO LISTEN ON THE INDICATED TERMINAL LINE

LOD039:	MOVE T1,LDLIN		;GET LINE DESIGNATOR
	CALL LISTEN		;GO SET UP LOWER FORK
	 ERRMSG(.ERR46,RET)	;COULD NOT ASSIGN LINE TO LISTEN ON
	RETSKP
; HERE TO ENTER INTO A DIALOG WITH THE DIAGNOSTIC

DGNCNV:	MOVE T1,LDDEV		;GET DTE20 NUMBER
	CALL TRMPRO		;TERMINATE ANY PROTOCOL RUNNING ON THE DTE
	 ERRMSG(.ERR47)
CNV04:	TMSG <[Enter ^E to return to DNLOAD]
>				;OUTPUT ADIVSORY MESSAGE
	CIS			;CLEAR THE INTERRUPT SYSTEM
	MOVX T1,.FHSLF		;GET OUT FORK HANDLE
	MOVE T2,[LEVTAB,,CHNTAB] ;GET TABLE ADDRESSES
	SIR			;TELL MONITOR WHERE TABLES ARE
	MOVE T1,[.TICCE,,1]	;CHANNEL 1 IS CONTROL/E
	ATI			;ATTACH TERMINAL CHARACTER TO CHANNEL
	MOVE T1,[1,,[ MOVEI T1,PARSE ;GET ADR OF ROUTINE TO FIELD CONTROL/E
		      MOVEM T1,RETPC1 ; INTERRUPTS.
		      MOVEI T1,101	;GET PRIMARY JFN
		      RFMOD		;READ JFN MODE WORD
		       ERJMP JSERR0	;UNEXPECTED ERROR
		      MOVEI T4,1	;ECHOING WANTED AGAIN !
		      STOR T4,TT%ECO,T2	; . . .
		      SFMOD		;SET THE JFN MODE WORD
		       ERJMP JSERR0	;UNEXPECTED ERROR
		      SKIPE T1,PROCES	;A LOWER FORK NOW LISTENING ?
		      FFORK		;YES, FREEZE IT !
		       ERCAL R		;IGNORE ERRORS
		      DEBRK		;DISMISS AND RETURN TO PARSER CODE
		      ERJMP JSHLT0]]	;UNEXPECTED FAILURE
	MOVEM T1,ICH001		;SAVE LEVEL AND INTERRUPT ROUTINE ADDRESS
	MOVX T1,.FHSLF		;GET OUR FORK HANDLE
	MOVX T2,1B1		;CHANNEL 1 BIT
	AIC			;ACTIVATE CHANNEL 1	
	EIR			;ENABLE ENTIRE INTERRUPT SYSTEM
	MOVEI T1,101		;GET PRIMARY JFN
	RFMOD			;READ JFN MODE WORD
	 ERJMP JSERR0		;UNEXPECTED ERROR
	MOVEI T4,0		;NO ECHOING IS WANTED ON FURTHER CHARACTERS
	STOR T4,TT%ECO,T2	; ENTERED DURING THIS DIALOG
	SFMOD			;SET THE JFN MODE WORD
	 ERJMP JSERR0		;UNEXPECTED ERROR
	
	SETZ T2,		;[21] Do this in order to initialize T3
TALK10:	MOVE T3,T2		;[21] Save character output previously
	CALL GETTXT		;GO GET TEXT TO SEND TO DIAGNOSTIC
	 RET			;FAILED
	LDB T2,[POINT 7,DCOMND,6] ;GET CHARACTER
	JUMPE T2,TALK10		;IGNORE NULLS
	CAIE T2,.CHLFD		;[21] Is it a line feed?
	IFSKP.			;[21] Yes
	  CAIN T3,.CHCRT	;[21] Was the previous character a CR?
	  JRST TALK10		;[21] Yes, so don't send the LF
	ENDIF.			;[21]
	MOVE T1,LINJFN		;GET JFN TO OUTPUT TO
	BOUT			;OUTPUT THE CHARACTER
	 ERJMP JSERR0		;FAILED, ISSUE ERROR MESSAGE
	JRST TALK10		;GO GET NEXT COMMAND
SUBTTL	CONVERSE (WITH) MCBN:
;
; COMMAND TO BEGIN A CONVERSATION WITH A SECONDARY PDP-11 WITHOUT
;  DISTURBING ITS PROGRAM.
;
.CONVR:
	MOVX T1,<.DVDES+.DVNUL,,-1> ;GET DESIGNATOR FOR NULL
	MOVEM T1,LDLIN
	HRROI T2,[ASCIZ/WITH/]	;GET GUIDE PHRASE
	CALL SKPNOI		;PARSE NOISE WORDS
	 RET			;FAILED, RETURN.
	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[FLDDB. (.CMDEV)]
	COMND			;PARSE A DEVICE NAME
	 ERJMP CMDERR		;GO TEST FOR EOF ON FAILURE
	TXNN T1,CM%NOP		;PARSED DEVICE NAME OK?
	JRST CNV01		;YES.
	CALL TSTCOL		;NO, ISSUE NEW LINE IF NEEDED
	HRROI T1,[ASCIZ/INVALID DEVICE NAME/]
	CALLRET TYPATM		;GO TYPE AND RETURN
;
CNV01:	LOAD T4,CM%FNC,(T3)	;GET FUNCTION CODE PARSED
	CAIE T4,.CMDEV		;PARSED A DEVICE?
	JRST CNV02		;NO, DONT DISTURB ORIGINAL VALUE
	MOVEM T2,LDLIN		;YES, SAVE DESIGNATOR
	CALL ENDCOM		;PARSE END OF COMMAND
	 RET			;FAILED
CNV02:	MOVE T1,LDLIN		;GET DESIGNATOR FOR CONVERSATION LINE
	DVCHR			;GET DEVICE CHARACTERISTICS
	LOAD T4,DV%TYP,T2	;GET DEVICE TYPE
	CAIE T4,.DVTTY		;A TERMINAL LINE?
	 ERRMSG(.ERR22,RET)	;LISTENING DEVICE NOT A TERMINAL
;
CNV03:	MOVE T1,LDLIN		;GET LINE DESIGNATOR
	CALL LISTEN		;GO SET UP LOWER FORK
	 ERRMSG(.ERR46,RET)	;
	JRST CNV04		;GO RUN END OF "LOAD" CODE
;
;LISTEN - ROUTINE TO SET UP TO LISTEN ON A TERMINAL LINE


; SET UP A LOWER FORK TO LISTEN TO TERMINAL LINE

LISTEN:	ASUBR <LDES>		;LINE DESIGNATOR
	SKIPE T1,LINJFN		;WAS ANOTHER LINE BEING LISTENED TO ?
	JRST [	CLOSF		;YES, CLOSE THE FILE
		 JFCL		;IGNORE FAILURE, UNIMPORTANT
		JRST .+1]	;CONTINUE WITH MAINLINE CODE
	HRRZ T1,LDES		;GET LINE DESIGNATOR
	TXO T1,.TTDES		;FORM TERMINAL DESIGNATOR
	MOVX T2,.MOSNT		;SEND TO TERMINAL PARAMETER
	MOVX T3,.MOSMN		;SEND NO SYSTEM MESSAGES TO THIS TERMINAL
	MTOPR			;TELL MONITOR
	 ERJMP R		;FAILED, RETURN ERROR TO CALLER
	MOVX T2,.MOSIG		;SET "IGNORE INPUT" BIT
	MOVX T3,1		;SET TO 1
	MTOPR			;TELL MONITOR
	 ERJMP R		;FAILED, RETURN ERROR TO CALLER
	HRROI T1,STRING		;GET POINTER TO TEMPORARY STRING AREA
	MOVE T2,LDES		;GET DESIGNATOR OF LINE TO LISTEN ON
	DEVST			;CONVERT DESIGNATOR TO STRING
	 RET			;FAILED, RETURN ERROR
	MOVEI T2,":"		;GET DEVICE NAME TERMINATOR
	IDPB T2,T1		;ADD TERMINATING PUNCTUATION TO STRING
	MOVEI T2,.CHNUL		;GET TERMINATOR FOR STRING
	IDPB T2,T1		;ADD A NULL TO THE STRING
	MOVX T1,GJ%SHT!GJ%OLD	;SHORT CALL, EXISTING FILE
	HRROI T2,STRING		;POINTER TO FILENAME
	GTJFN			;GET A JFN FOR THE TERMINAL TO LISTEN ON
	 RET			;FAILED, RETURN ERROR
	MOVEM T1,LINJFN		;SAVE FOR INFERIOR FORK
	MOVE T2,[70000,,OF%RD!OF%WR] ;READ, WRITE  ACCESS, 7 BIT BYTES
	OPENF			;OPEN THE FILE
	 RET			;FAILED, RETURN ERROR
	CFIBF			;CLEAR FILE INPUT BUFFER
	 ERJMP R		;UNEXPECTED FAILURE
	MOVX T2,.TTIDL		;GET "IDEAL" TERMINAL TYPE NUMBER
	STTYP			;SET TERMINAL TYPE, SO THERE IS NO PADDING
	 ERJMP R		;RETURN FAILURE ON UNEXPECTED ERROR
	; ..
	; ..

	MOVE T1,LDES		;GET DESIGNATOR OF LINE TO LISTEN ON
	DVCHR			;GET DEVICE CHARACTERISTICS
	LOAD T4,DV%TYP,T2	;GET DEVICE TYPE
	CAIE T4,.DVNUL		;IS DEVICE DEFAULTED TO NUL: ?
	JRST [	DMOVE T2,[525252,,525252
			  525252,,525252] ;GET CONTROL CHAR OUTPUT CONTROL WORDS
		SFCOC		;TURN OFF CONTROL CHAR TRANSLATION
		 ERJMP R	;RETURN ERROR ON FAILURE
		RFMOD		;READ THE JFN MODE WORD
		 ERJMP R	;RETURN ERROR ON FAILURE
		MOVEI T4,-1	;TURN ON ALL WAKEUP BITS
		STOR T4,TT%WAK,T2 ;TURN ON THE BITS IN THE JFN MODE WORD
		MOVEI T4,0	;BUT ECHOING SHOULD BE TURNED
		STOR T4,TT%ECO,T2 ; OFF COMPLETELY
		SFMOD		;SET THE NEW JFN MODE WORD
		 ERJMP R	;RETURN FAILURE ON ERROR
		JRST .+1 ]	;RETURN TO MAINLINE CODE
	SKIPE T1,PROCES		;ANY PREVIOUS FORK ?
	JRST [	KFORK		;YES, TRY TO KILL IT
		 ERJMP .+1	;IGNORE FAILURE
		JRST .+1 ]	;RETURN TO MAINLINE CODE
	MOVX T1,CR%MAP!CR%ST	;SAME MAP AS SUPERIOR, START AT ADDRESS IN T2
	HRRI T1,TXTTST		;ADDRESS TO START EXECUTION AT
	CFORK			;CREATE AN INFERIOR PROCESS
	 RET			;FAILED, RETURN ERROR
	MOVEM T1,PROCES		;SAVE PROCESS HANDLE OF LISTENING PROCESS
	RETSKP			;DONE, RETURN SUCCESS





; CODE EXECUTED BY INFERIOR PROCESS TO LISTEN ON A TERMINAL LINE

TXTTST:	HRRZ T1,LINJFN		;GET DESIGNATOR TO LISTEN ON
	BIN			;INPUT A CHARACTER
	JUMPE T2,TXTTST		;SKIP NULLS
	MOVE T1,T2		;COPY THE CHARACTER
	PBOUT			;OUTPUT THE CHARACTER
	CAIN T2,.CHCRT		;WAS THIS CHARACTER A CARRIAGE-RETURN ?
	JRST [	MOVE T1,LINJFN	;YES, GET JFN AGAIN
		BIN		;SKIP OVER THE FREE LINE FEED
		JRST .+1 ]	;CONTINUE IN MAINLINE CODE
	JRST TXTTST		;GO DO NEXT CHARACTER
;TRMPRO - ROUTINE TO TERMINATE THE PROTOCOL RUNNING ON A DTE20
;
;ACCEPTS IN T1/	DTE20 NUMBER
;		CALL TRMPRO
;RETURNS: +1 	 FAILED, ERROR MESSAGE OUTPUT TO TERMINAL
;	  +2	SUCCESS, PROTOCOL TERMINATED

STPPRO:	MOVE	T1,LDDEV	;stop protocol on dte

TRMPRO:	ASUBR <TPDTE>
	CALL	CLRBOT		;CLEAR BOOT BLOCK
	MOVE	T1,TPDTE	;GET BACK DTE #
	MOVEM T1,BTARG+.BTDTE	;SAVE DTE20 NUMBER IN JSYS ARG BLOCK
	MOVEI T1,.BTTPR		;GET "TERMINATE PROTOCOL" FUNCTION CODE
	MOVEI T2,BTARG		;GET ADDRESS OF BOOT JSYS ARGUMENT BLOCK
	BOOT			;TERMINATE ANY PROTOCOL PREVIOUSLY RUNNING
	 ERJMP BTERR		;FAILED, NOTE ERROR
	RETSKP			;DONE, RETURN SUCCESS
;
;INIPRO - ROUTINE TO INITIATE PROTOCOL ON A LINE
;
;		CALL INIPRO
;RETURNS +1	 FAILED
;        +2	SUCCEEDED

INIPRO:	SKIPE	LDFLG		;IF DIAGNOSTIC LOAD, DON'T START PROTOCOLS
	 RETSKP			;RETURN OKAY THOUGH
	SKIPE	LDTYP		;DDCMP OR DTE  PROTOCOL?
	 JRST	INIDMC		;GO HANDLE DDCMP DIFFERENTLY
	CALL	CLRBOT		;CLEAR BOOT AREA
	MOVE	T1,LDDEV	;GET THE DTE #
	MOVEI	T2,BTARG
	MOVEM	T1,.BTDTE(T2)	;STORE IN ARG BLOCK
	MOVEI	T1,.BTBEL	;WAIT FOR DOORBELL
	BOOT			;GO WAIT FOR IT
	 ERJMP	R
	CALL	CLRBOT		;CLEAR
	MOVE	T1,LDDEV	;DTE #
	MOVEM	T1,.BTDTE+BTARG ;INTO ARG BLOCK
	MOVE	T1,PTYPE	;get the protocol version to start
	MOVEM	T1,BTARG+.BTPRV ;SAVE AS PROTOCOL VERSION
	MOVEI	T1,.BTIPR	;INITIATE PROTOCOL FUNCTION
	MOVEI	T2,BTARG	;POINT TO ARG BLOCK FOR JSYS
	BOOT			;DO IT
	 ERJMP	R
	RETSKP			;SUCCEEDED

;no need to start protocol from this side since dmc will do that.  just
;wait for the start exchange to complete

INIDMC:				;HERE TO INITIATE A DN22 DDCMP LINE
	MOVEI	P1,30		;NUMBER OF TIMES TO CHECK FOR INIT COMPLETE
INICHK:	CALL	CLRBOT		;CLEAR BOOT ARG BLOCK
	MOVEI	T2,BTARG	;
	MOVE	T1,LDDEV	;UNIT TO LOAD
	MOVEM	T1,.BTDTE(T2)	;PUT UNIT NUMBER IN JSYS ARG BLOCK
	MOVEI	T1,.BTRDD	;READ A COMPLETION POST
	BOOT
	 ERJMP	R
	SKIPN	.BTLEN(T2)	;ZERO IMPLIES NO DATA WAS AVAILABLE YET
	JRST	[SOSGE	P1	;DECREMENT # OF TRIES
		 ERRMSG(,RET)	;TRIED ENOUGH
		 MOVEI	T1,^D5000 ;WAIT 5 SEC BEFORE TRYING AGAIN
		 DISMS
		 JRST	 INICHK	;TRY AGAIN
		]
	SKIPL	T2,.BTLEN(T2)	;EXPECTING SIGN BIT ON
	 ERRMSG(,RET)
	HRRZS	T2		;ONLY RH
	CAIE	T2,1		;IS LINE NOW UP?
	 ERRMSG(,RET)		;NO
	RETSKP
;
;INIDDC - ROUTINE TO INITIALIZE A 2020 SYN LINE AS DDCMP LINE
;
;	CALL INIDDC
;
;RETURNS +1 ERROR
;        +2 SUCCESS
;
INIDDC:
	SKIPN	LDTYP		;DON'T DO THIS FOR A DTE
	 RETSKP
	CALL	CLRBOT		;CLEAR BOOT JSYS ARG BLOCK
	MOVEI	T2,BTARG	;ADDRESS OF ARG BLOCK
	MOVE	T1,LDDEV	;DEVICE BEING INIT'D
	MOVEM	T1,.BTDTE(T2)	;
	MOVEI	T1,.DCPL	;DDCMP LINE SERVICE TYPE
	MOVEM	T1,.BTCOD(T2)	;STORE LINE SERVICE
	MOVEI	T1,.BTSLS	;SET LINE SERVICE FUNCTION CODE
	BOOT
	 ERJMP	R
	RETSKP
SUBTTL DUMP COMMAND
.DUMP:
	HRROI	T2,[ASCIZ\DEVICE\]
	CALL	SKPNOI		;PROMPT FOR DEVICE TO DUMP
	 BADCMD(.ERR2,RET)
	MOVEI	T1,CMDBLK	;ADDRESS OF COMMAND BLOCK
	MOVEI	T2,[FLDDB. (.CMKEY,,DPDVTB)] ;DEVICES WE CAN DUMP
	COMND			;PARSE THE COMMAND
	 ERJMP	CMDERR		;ERROR
	TXNE	T1,CM%NOP	;CORRECT PARSE?
	 BADCMD(.ERR1,RET)
	HRRZ	T1,(T2)		;DISPATCH TO CORRECT ROUTINE
	JRST	(T1)

DMPDTE:	TDZA	T1,T1		;WE'RE DUMPING A DTE
DMP200:	SETOM	T1		;WE'RE DUMPING A DN200/DN22
	MOVEM	T1,LDTYP	;SO WE REMEMBER WHICH
	HRROI	T2,[ASCIZ\ON LINE/DTE\] ;NOISE WORD
	CALL	SKPNOI
	 BADCMD(.ERR2,RET)	;IMPROBABLE
	MOVEI	T1,CMDBLK	;COMMAND BLOCK
	MOVEI	T2,[FLDDB. (.CMNUM,,^D8)]
	COMND			;GET UNIT NUMBER FIELD
	 ERJMP	CMDERR
	TXNE	T1,CM%NOP	;UNIT NUMBER CORRECT?
	 BADCMD(.ERR7,RET)		;NO
	MOVEM	T2,LDDEV	;SAVE DUMP DEVICE
	HRROI	T2,[ASCIZ/TO/]	;NOISE WORD
	CALL	SKPNOI
	 BADCMD(.ERR2,RET)
	DEFFIL	GJ%FOU,DSK:,,DUMP0,DMP
	MOVEI	T1,CMDBLK	;COMMAND BLOCK ADDRESS
	MOVEI	T2,[FLDDB. (.CMFIL)] ;PARSE OUTPUT FILE SPEC
	COMND
	 ERJMP	CMDERR
	TXNE	T1,CM%NOP	;FILE SPEC CORRECT?
	 BADCMD(.ERR17,RET)		;NO
	MOVEM	T2,LDFIL	;SAVE JFN OF FILE PARSED
	CALL	ENDCOM		;PARSE END OF COMMAND
	 ERRMSG(.ERR21,RET)
	MOVE	T1,LDFIL	;JFN TO OPEN
	MOVE	T2,[440000,,OF%WR] ;8-BIT BYTES AND WRITE ENABLE
	OPENF
	 ERJMP	[ERRMSG(.ERR33,RET)]
	SKIPN	LDTYP		;DOING THE DN200?
	 JRST	DMPDT0		;GO DO DUMP OF A DTE DIFFERENTLY
	MOVE	T1,SECDMP	;GET THE DUMPER BOOTSTRAP
	CALL	OPNIFL		;OPEN THE DUMPER BOOT FILE
	 ERRMSG (.ERR27,DMPCLS)
	STOR	T1,RBJFN	;SAVE THE JFN
	MOVEI	T2,.PTSLD	;THIS IS A SECONDARY BOOTSTRAP
	STOR	T2,RBPTYP	;SAVE FOR OTHERS TO SEE
	MOVEI	T2,PRISIZ	;MUST GO AS ONE LOAD IMAGE
	MOVEM	T2,MAXMEM	;
	CALL	RQLOD		;LOAD THE BOOTSTRAP
	 ERRMSG(,DMPERX)
	CALL	CLSFIL		;CLOSE THE DUMPER FILE
	CALL	CHKMMR		;CHECK THE "MOP MODE RUNNING" MSG
	 ERRMSG(.ERR35,DMPCLS)
	MOVEI	T2,SECSIZ	;SIZE OF BUFFERS TO SEND TO SECONDARY LDR
	MOVEM	T2,MAXMEM	;FOR I/O ROUTINES
	MOVE	T1,LDMSIZ	;GET THE TOTAL MEMORY SIZE OF TARGET
	STOR	T1,RBFCT	;SAVE AS TOTAL FILE SIZE
	MOVEI	T1,0		;START DUMPING AT LOCATION 0
	STOR	T1,RBNAD	;STORE AS NEXT DUMP ADDRESS
	
DMP030:	LOAD	T1,RBNAD	;GET THE NEXT ADDRESS TO DUMP
	STOR	T1,RBCAD	;STORE AS NEW CURRENT ADDRESS TO DUMP
	LOAD	T1,RBFCT	;GET # BYTES LEFT TO DUMP
	MOVE	T2,T1	
	CAMLE	T1,MAXMEM	;WILL IT ALL FIT IN BUFFER?
	MOVE	T1,MAXMEM	;NO, USE THE MAXIMUM
	SUB	T2,T1		;UPDATE WHAT'S LEFT
	STOR	T2,RBFCT	; ...
	STOR	T1,RBCNT	;NUMBER OF BYTES TO TRANSFER THIS TIME
	LOAD	T2,RBCAD	;GET CURRENT START ADDRESS FOR DUMP
	ADD	T2,T1		;
	STOR	T2,RBNAD	;UPDATE NEW NEXT ADDRESS
	CALL	MAKRQD		;MAKE A "REQUEST DUMP DATA" MESSAGE
	 JFCL			;SHOULD NEVER HAPPEN
	MOVEI	T1,NTRIES	;NUMBER OF TIMES TO TRY
	MOVEM	T1,LDRTRY	;...
DMPAGN:	CALL	MOPSND		;SEND OUT THE MESSAGE
	 ERRMSG(.ERR37,DMPCLS)
	CALL	MOPRCV		;GO RECEIVE THE ANSWER
	 JRST	[SKIPG	LDRTRY	;TRIED ENUFF?
	 	 ERRMSG(.ERR40,DMPCLS)		;NO ANSWER
		 SOS	LDRTRY	;TRY ONCE MORE
		 JRST	DMPAGN]
	CALL	CHKMDD		;CHECK THE ANSWER
	 ERRMSG(.ERR41,DMPCLS)		;ANSWER INCORRECT
	MOVE	P3,[POINT	8,RMPMSG+1,7] ;POINTER TO START OF DMP DATA
	MOVEI	P1,0		;BYTE COUNTER
	LOAD	P2,RBCNT	;TOTAL COUNT OF DUMP DATA
	MOVEI	T1,RMPMSG	;WHERE TO PUT SHUFFLED DATA
SHUFFL:	ILDB	T2,P3		;GET NEXT BYTE FROM MESSAGE
	MOVE	T3,P1		;
	ANDI	T3,3		;WHICH BYTE IN WORD TO PUT SHUFFLED DATA
	DPB	T2,DBYTTB(T3)	;PUT IT THRER
	CAIN	T3,3		;DONE THIRD BYTE YET?
	ADDI	T1,1		;YES,INCREMENT TO NEXT WORD
	ADDI	P1,1		;INCREMENT # BYTES SHUFFLED
	SOJG	P2,SHUFFL	;IF MORE CONTINUE
	MOVE	T1,LDFIL	;THE DUMP FILE JFN
	MOVE	T2,[POINT 36,RMPMSG]	;POINTER TO START OF DUMP DATA
	LOAD	T3,RBCNT	;GET THE NUMBER OF BYTES
	ADDI	T3,3		;ROUND TO # OF 36-BIT WORDS
	LSH	T3,-2
	MOVNS	T3		;MAKE -VE FOR SOUT
	SOUT
	 ERJMP [ERRMSG(.ERR42,DMPCLS)]
	LOAD	T1,RBFCT	;GET THE REMAINING COUNT
	SKIPE	T1		;ANYTHING LEFT?
	JRST	DMP030		;YES, CONTINUE
	CALL	DMPCLS
	RETSKP

DMPERX:	CALL	CLSFIL
	JRST	DMPCLS
SUBTTL	DUMP (DTE20) N (TO) FILE-SPEC

;HERE TO DUMP A DTE.  THIS IS DONE ENTIRELY BY THE ROM SO THERE IS NO PROTOCOL
;INVOLVED.

DMPDT0:
	CALL CLRBOT		;
	MOVEI T1,.BTROM		;GET BOOT JSYS FUNCTION CODE
	MOVEI T2,BTARG		;GET ADDRESS OF ARG BLOCK (DTE # ALREADY THERE)
	MOVE	T4,LDDEV	;[3(4)] GET DEVICE TO BE DUMPED
	MOVEM	T4,BTARG+.BTDTE ;[3(4)] STORE IN BOOT ARG BLOCK
	BOOT			;TRIGGER THE BOOTSTRAP ROM
	 ERJMP BTERR		;FAILED

; LOOP OVER EACH PAGE OF DATA

	MOVSI P1,-MEMSIZ	;SET UP TO LOOP OVER EACH PAGE
DMP025:	MOVE T4,[POINT 18,RMPMSG] ;GET POINTER TO DATA AREA
	MOVEM T4,BTARG+.BTDPT	;STORE POINTER FOR BOOT JSYS
	MOVEI T4,1000*2		;GET NUMBER OF BYTES TO DUMP
	MOVEM T4,BTARG+.BTCNT	;STORE COUNT OF FOR BOOT JSYS
	MOVEI T1,.BTDMP		;GET DUMP FUNCTION CODE
	MOVEI T2,BTARG		;GET ADDRESS OF ARGUMENT BLOCK
	BOOT			;GET SOME DUMP DATA
	ERJMP	[CALL BTERR	;FAILED, TYPE ERROR MESSAGE
		 JRST DMPCLS]
	MOVE T1,LDFIL		;GET DUMP FILE JFN
	MOVE T2,[POINT 36,RMPMSG] ;GET POINTER TO DATA TO DUMP
	MOVNI T3,1000		;NUMBER OF WORDS TO DUMP
	SOUT			;OUTPUT DATA TO FILE
	 ERJMP	[ERRMSG(.ERR42,DMPCLS)]
	AOBJN P1,DMP025		;GO DO NEXT PAGE OF FILE

; CLOSE THE OUTPUT FILE

DMPCLS:	MOVE T1,LDFIL		;GET JFN OF OUTPUT FILE
	CLOSF			;CLOSE THE FILE
	 ERRMSG(.ERR42,RET)	;FAILED, NOTE FAILURE AND CONTINUE
	RET			;DONE, RETURN
SUBTTL DUMP KMC
DMPKMC:		TRVAR <<BTDBLK,14>,<BTDPAG,2>,BTDFIL>
	MOVEI	T1,0		;DUMP ONLY 0
	IMULI	T1,10
	ADD	T1,[3,,760540]	;THIS IS KMC11 ADDRESS
	MOVEM T1,.BTKMC+BTDBLK	;SAVE ADR OF KMC11
	HRROI	T2,[ASCIZ/TO/]	;NOISE WORD
	CALL	SKPNOI
	 BADCMD(.ERR2,RET)
	MOVEI	T1,CMDBLK	;COMMAND BLOCK ADDRESS
	MOVEI	T2,[FLDDB. (.CMFIL)] ;PARSE OUTPU FILE SPEC
	COMND
	 ERJMP CMDERR
	TXNE	T1,CM%NOP	;FILE SPEC OKAY?
	 BADCMD(.ERR17,RET)	;NO
	MOVEM T2,BTDFIL		;SAVE JFN TO FILE SPEC FOR LATER
	CALL	ENDCOM		;END OF COMMAND
	 ERRMSG(.ERR21,RET)
	MOVE T1,BTDFIL		;COPY JFN OF FILESPEC
	MOVE T2,[070000,,OF%WR]	;7-BIT BYTES, WRITE ACCESS ONLY
	OPENF			;OPEN THE FILE
	 ERJMP	[ERRMSG(.ERR33,RET)]
	MOVEI	T2,CRAMPG	;CRAM PAGE ADDRESS
	MOVEM T2,BTDPAG		;SAVE ADR OF FIRST WORD IN PAGE
	MOVEI	T2,DRAMPG	;ADDRESS OF DRAM PAGE
	MOVEM T2,1+BTDPAG	;SAVE ADR OF FIRST WORD IN PAGE
	MOVEI T1,20		;NUMBER OF REGISTERS TO GET
	MOVEM T1,.BTKRC+BTDBLK
	ADD T2,[POINT 16,400]	;GET 16 BIT BYTES
	MOVEM T2,.BTKRP+BTDBLK	;WHERE TO PUT REGISTERS
	MOVEI T1,2000		;NUMBER OF DRAM BYTES TO GET
	MOVEM T1,.BTKDC+BTDBLK
	MOVE T2,1+BTDPAG	;GET ADR OF PAGE AGAIN
	HRLI T2,(POINT 8,)	;8 BIT BYTES FOR DRAM
	MOVEM T2,.BTKDP+BTDBLK
	MOVEI T1,2000		;NUMBER OF CRAM LOCATIONS TO GET
	MOVEM T1,.BTKCC+BTDBLK	;NUMBER OF CRAM WORDS TO GET
	MOVE T2,BTDPAG		;GET ADR OF PAGE
	HRLI T2,(POINT 16,)	;16 BIT BYTES FOR CRAM
	MOVEM T2,.BTKCP+BTDBLK
	MOVEI T1,.BTKMD		;WANT TO DUMP THE KMC11
	MOVEI T2,BTDBLK		;POINT TO ARGUMENT BLOCK
	BOOT
	 ERJMP [ERRMSG(.ERR42,RET)]
	;..
	;..
	MOVE T1,BTDFIL
	HRROI T2,[ASCIZ \	Register data\]
	MOVEI T3,20		;NUMBER OF REGISTERS WE ASKED FOR
	SUB T3,.BTKRC+BTDBLK	;MAKES NUMBER OF REGISTERS WE GOT
	MOVE T4,1+BTDPAG	;POINT TO REGISTER DATA
	ADD T4,[POINT ^D16,400]	;16 BIT BYTES
	CALL DMPLDT		;DUMP THE REGISTERS
	HRROI T2,[ASCIZ \	DRAM data\]
	MOVEI T3,2000		;NUMBER OF DRAM WE ASKED FOR
	SUB T3,.BTKDC+BTDBLK	;MAKES NUMBER OF DRAM WE GOT
	MOVE T4,1+BTDPAG	;POINT TO DRAM DATA
	HRLI T4,(POINT 8,)	;8 BIT BYTES
	CALL DMPLDT		;DUMP THE DRAM
	HRROI T2,[ASCIZ \	CRAM data\]
	MOVEI T3,2000		;NUMBER OF CRAMS WE ASKED FOR
	SUB T3,.BTKCC+BTDBLK	;MAKES NUMBER OF CRAMS WE GOT
	MOVE T4,BTDPAG		;POINT TO CRAM DATA
	HRLI T4,(POINT 16,)	;16 BIT BYTES
	CALL DMPLDT		;DUMP THE CRAMS
	SETZ T4,		;DUMP WON
	HRRZ T1,BTDFIL		;GET DUMP JFN
	CLOSF			;CLOSE FILE
	 JFCL
	RET
DMPLDT:	MOVEM T3,.BTKRC+BTDBLK	;SAVE COUNT OF DATA
	MOVEM T4,.BTKRP+BTDBLK	;SAVE POINTER TO DATA
	MOVEM T2,.BTKERR+BTDBLK	;SAVE TYPE OF DATA
	HRROI T2,[ASCIZ \Dump of KDP_\]
	SETZ T3,
	SOUT
	MOVE T2,.BTKMC+BTDBLK	;GET KMC11 ADR
	SUB T2,[3,,760540]	;MAKE RELATIVE KMC ADR
	LSH T2,-3		;MAKE UNIT NUMBER
	MOVEI T3,^D8		;OCTAL
	NOUT
	 ERJMP .+1
	HRROI T2,[ASCIZ \ made on \]
	SETZ T3,
	SOUT
	SETO T2,		;CURRENT DATE AND TIME
	SETZ T3,		;FORMAT
	ODTIM
	MOVE T2,.BTKERR+BTDBLK	;GET TYPE OF DATA
	SETZ T3,
	SOUT
	SETZ T4,		;FIRST ADR TO DUMP
DMPLD2:	TRNE T4,7		;TIME FOR A CR/LF ?
	JRST DMPLD4		;NO
	CALL DMPCRL		;PUT OUT A CR/LF
	TRNN T4,37		;TIME FOR AN EXTRA CR/LF
	CALL DMPCRL		;PUT OUT A CR/LF
	MOVE T2,T4		;CURRENT LOCATION NUMBER
	MOVE T3,[NO%LFL+6B17+10] ;OCTAL
	NOUT			;PUT CURRENT LOCATION NUMBER
	ERJMP .+1
	MOVEI T2,"/"
	BOUT
DMPLD4:	ILDB T2,.BTKRP+BTDBLK	;GET NEXT PIECE OF DATA
	MOVE T3,[NO%LFL+10B17+^D8] ;LEADING FILLER
	NOUT			;PRINT DATA
	JFCL
	SOSLE .BTKRC+BTDBLK	;ANY LEFT ?
	AOJA T4,DMPLD2		;ON TO NEXT LOCATION
	CALL .+1		;ADD CR/LF
	CALL DMPCRL		;END WITH A CR/LF
	;RET			;ALL DONE

;HERE TO PUT OUT A CR/LF
DMPCRL:	HRROI T2,[BYTE (7)15,12,0] ;CR/LF
	SETZ T3,
	SOUT
	RET
; ERROR ROUTINES

BTERR:	CALL TSTCOL
	TMSG <? DNLOAD: BOOT JSYS FAILED, ERROR IS:
	>
	CALL PUTERR
	TMSG <
>
	RET
;GETTXT - ROUTINE TO INPUT TEXT TO SEND TO A DIGANOSTIC PROGRAM


GETTXT:	MOVE T1,[TXTBLK,,TXTBLK+1] ;SET UP TO CLEAR TEXTI BLOCK
	SETZM TXTBLK		;CLEAR FIRST WORD OF BLOCK
	BLT T1,TXTBLK+TXTSIZ-1	;CLEAR REMAINDER OF BLOCK
	MOVEI T1,TXTSIZ		;GET SIZE OF ARG BLOCK
	MOVEM T1,TXTBLK+.RDCWB	;STORE IN COUNT WORD FOR BLOCK
	MOVEI T1,[ -1
		   -1
		   -1
		   -1 ]		;BREAK ON ALL CHARACTERS
	MOVEM T1,TXTBLK+.RDBRK	;SET UP SPECIAL BREAK SET
	MOVX T1,RD%BEL!RD%JFN!RD%BBG!RD%RAI ;GET FLAG BITS
	MOVEM T1,TXTBLK+.RDFLG	;SAVE FLAGS IN ARG BLOCK
	MOVE T1,[.PRIIN,,.PRIOU] ;GET INPUT AND OUTPUT JFN'S
	MOVEM T1,TXTBLK+.RDIOJ	;SAVE JFN'S
	HRROI T1,DCOMND		;GET POINTER TO DIAGNOSTIC COMMAND
	MOVEM T1,TXTBLK+.RDDBP	;SAVE POINTER TO DESTINATION STRING
	MOVEI T1,DCOSIZ*NCHPW	;GET # OF CHARACTERS IN DIAG COMMAND BUFFER
	MOVEM T1,TXTBLK+.RDDBC	;SAVE SIZE OF BUFFER
	HRROI T1,DCOMND		;GET POINTER TO START OF COMMAND BUFFER
	MOVEM T1,TXTBLK+.RDBFP	;SAVE POINTER IN JSYS ARG BLOCK
	SETZM TXTBLK+.RDRTY	;NO PROMPT POINTER
	SETZM TXTBLK+.RDBKL	;NO BACKUP LIMIT NEEDED
	MOVEI T1,TXTBLK		;GET POINTER TO TEXTI BLOCK
	TEXTI			;INPUT COMMAND TO SEND
	 ERJMP [CALL TSTCOL	;FAILED, ISSUE NEW LINE IF NEEDED
		TMSG <? DNLOAD: TEXTI JSYS failed, internal program error
>		RET ]		;RETURN
	LDB T1,[POINT 7,DCOMND,6] ;GET THE CHARACTER JUST ENTERED
	CAIN T1,.CHCRT		;A CARRIAGE RETURN ?
	JRST [	MOVEI T1,.CHNUL	;YES, GET A NULL
		DPB T1,[POINT 7,DCOMND,13] ;REPLACE THE LINE FEED WITH A NULL
		JRST .+1 ]	;CONTINUE WITH MAINLINE CODE
	RETSKP			;DONE, TEXT INPUT. RETURN SUCCESS
SUBTTL	RESUME (LISTENING)

.RESUM:	HRROI T2,[ASCIZ/LISTENING/]
	CALL SKPNOI		;PARSE NOISE WORDS
	 RET			;FAILED
	CALL ENDCOM		;PARSE END OF COMMAND
	 RET			;FAILED
	SKIPN T1,PROCES		;WAS THERE A LOWER FORK ?
	JRST NOFORK		;NO, ISSUE MESSAGE
	RFORK			;YES, RESUME THE LOWER FORK
	 ERJMP .+1		;IGNORE ERRORS
	JRST DGNCNV		;GO BACK INTO DIALOG MODE

NOFORK:	CALL TSTCOL		;ISSUE NEW LINE IF NEEDED
	TMSG <% DNLOAD: No listening in progress...
>				;OUTPUT MESSAGE
	RET			;DONE, RETURN
SUBTTL	TAKE (COMMANDS FROM) FILE-SPEC (LOGGING OUTPUT ON) FILE-SPEC

.TAKE:	HRROI T2,[ASCIZ/COMMANDS FROM/] ;GET NOISE TEXT
	CALL SKPNOI		;GO PARSE NOISE FIELD
	 RET			;FAILED, RETURN FAILURE
	CALL CLRGJF		;GO CLEAR GTJFN BLOCK
	MOVX T1,GJ%OLD		;GET EXISTING FILE FLAG
	MOVEM T1,GJFBLK+.GJGEN	;STORE GTJFN FLAGS
	HRROI T1,[ASCIZ/CMD/]	;GET DEFAULT FILE TYPE FIELD
	MOVEM T1,GJFBLK+.GJEXT	;STORE DEFAULT EXTENSION
	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[FLDDB. (.CMFIL)] ;GET FUNCTION DESCRIPTOR BLOCK ADDRESS
	COMND			;PARSE INPUT FILE SPEC
	 erjmp cmderr		;error, go check for eof on take file
	TXNN T1,CM%NOP		;PARSED FILE-SPEC OK ?
	JRST TAKE10		;YES, GO ON AND SAVE INPUT JFN
	CALL TSTCOL		;ISSUE NEW LINE IF NEEDED
	TMSG <? DNLOAD: Invalid file specification, >
	CALLRET PUTERR		;OUTPUT ERROR STRING TO TERMINAL

; HERE ON A GOOD INPUT FILE SPEC

TAKE10:	MOVEM T2,INJFN		;SAVE INPUT JFN FOR COMMANDS
	HRROI T2,[ASCIZ/LOGGING OUTPUT ON/] ;GET NOISE TEXT
	CALL SKPNOI		;GO PARSE NOISE FIELD
	 RET			;FAILED, RETURN FAILURE
	CALL CLRGJF		;GO CLEAR GTJFN BLOCK USED BY COMND JSYS
	MOVX T1,GJ%FOU		;GET FLAG SAYING FILEIS FOR OUTPUT USE
	MOVEM T1,GJFBLK+.GJGEN	;SAVE GTJFN FLAGS
	SETZM NAMBUF		;INITIALIZE FILENAME BUFFER
	HRROI T1,NAMBUF		;GET POINTER TO WHERE FILENAME IS TO GO
	MOVE T2,INJFN		;GET INPUT JFN
	MOVX T3,<FLD(.JSAOF,JS%NAM)> ;GET FLAG BITS SAYING OUTPUT NAME ONLY
	JFNS			;GET FILE NAME OF INPUT FILE
	SKIPE NAMBUF		;ANY FILENAME ?
	HRROI T1,NAMBUF		;YES, GET A POINTER TO THE FILE NAME FOR INPUT
	MOVEM T1,GJFBLK+.GJNAM	;STORE DEFAULT NAME OF OUTPUT FILE
	HRROI T1,[ASCIZ/LOG/]	;GET DEFAULT FILE TYPE OF OUTPUT FILE
	MOVEM T1,GJFBLK+.GJEXT	;STORE DEFAULT EXTENSION
	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[FLDDB. (.CMFIL)] ;GET FILE-SPEC FUNCTION BLOCK ADDRESS
	COMND			;PARSE OUTPUT FILE SPEC
	 erjmp cmderr		;error, go check for eof on take file
	TXNN T1,CM%NOP		;FILE SPEC PARSED OK ?
	JRST TAKE20		;YES, GO ON TO SAVE JFN
	CALL TSTCOL		;NO, ISSUE NEW LINE IF NEEDED
	TMSG <? DNLOAD: Invalid file specification, >
	CALLRET PUTERR		;GO OUTPUT CORRECT MESSAGE AND RETURN

; HERE TO SAVE OUTPUT JFN AND GET COMMAND CONFIRMATION

TAKE20:	MOVEM T2,OUTJFN		;SAVE LOGGIN FILE JFN
	CALL ENDCOM		;GO PARSE COMMAND CONFIRMATION
	 RET			;RETURN, BAD CONFIRMATION

; OPEN INPUT AND OUTPUT FILES

	MOVE T1,INJFN		;GET INPUT JFN
	MOVE T2,[7B5+OF%RD]	;7 BIT BYTES, READ ACCESS
	OPENF			;OPEN INPUT FILE
	 JRST [	CALL TSTCOL	;ERROR, ISSUE NEW LINE IF NEEDED
		TMSG <? DNLOAD: Cannot OPEN command file, >
		CALLRET PUTERR]	;GO ISSUE REST OF MESSAGE AND RETURN

	MOVE T1,OUTJFN		;GET OUTPUT JFN
	CAIN T1,.PRIOU		;STILL PRIMARY OUTPUT JFN ?
	JRST TAKE30		;NO OUTPUT JFN, GO ON
	MOVE T2,[7B5+OF%WR]	;7 BIT BYTES, WRITE ACCESS
	OPENF			;OPEN OUTPUT FILE
	 JRST [	CALL TSTCOL	;ERROR, ISSUE NEW LINE IF NEEDED
		MOVE T1,INJFN	;GET INPUT JFN AGAIN
		CLOSF		;CLOSE INPUT FILE
		 JFCL		;IGNORE ERRORS HERE
		TMSG <? DNLOAD: cannot OPEN logging file, >
		CALLRET PUTERR]	;GO OUTPUT REST OF MESSAGE

; NOW SAVE NEW JFN'S AND RETURN TO PARSER

TAKE30:	HRLZ T1,INJFN		;GET INPUT JFN
	HRR T1,OUTJFN		;GET OUTPUT JFN
	MOVEM T1,CMDBLK+.CMIOJ	;SAVE NEW JFN'S
	SETOM TAKFLG		;MARK THAT COMMANDS ARE COMING FROM FILE
	RET			;RETURN TO PARSER
SUBTTL	HELP AND EXIT COMMANDS

; HELP COMMAND

.HELP:	HRROI T2,[ASCIZ/WITH DNLOAD/] ;GET NOISE WORDS
	CALL SKPNOI		;GO PARSE NOISE FIELD
	 RET			;FAILED, RETURN FAILURE
	CALL ENDCOM		;GO PARSE END OF COMMAND
	 RET			;BAD CONFIRMATION, RETURN
	HRROI T1,HLPMSG		;GET POINTER TO HELP MESSAGE
	PSOUT			;OUTPUT HELP MESSAGE
	RET			;GO PARSE NEXT COMMAND

; EXIT COMMAND

.EXIT:	HRROI T2,[ASCIZ/TO MONITOR/] ;GET NOISE PHRASE
	CALL SKPNOI		;GO PARSE NOISE FIELD
	 RET			;FAILED, RETURN FAILURE
	CALL ENDCOM		;GO PARSE END OF COMMAND
	 RET			;BAD CONFIRMATION, RETURN
	SETOM T1		;INDICATE ALL FILES SHOULD BE CLOSED
	CLOSF			;CLOSE ALL OPEN FILES
	 JSERR			;UNEXPECTED ERROR
	SETOM T1		;AND RELEASE ALL ASSIGNED
	RELD			; DEVICES !
	 JFCL			;IGNORE FAILURE HERE
	HALTF			;RETURN TO MONITOR
	JRST START		;IF CONTINUE'D, START OVER
SUBTTL	COMMAND ERROR SUBROUTINES



; SUBROUTINE TO TEST COLUMN POSITION AND OUTPUT CRLF IF NEEDED

TSTCOL:	MOVEI T1,.PRIOU		;GET PRIMARY OUTPUT DESIGNATOR
	RFPOS			;READ FILE POSITION
	HRRZ T2,T2		;KEEP JUST THE COLUMN POSITION
	JUMPE T2,R		;IF AT COLUMN 1 DO NOT OUTPUT CRLF
	TMSG <
>				;NO, OUTPUT A CRLF
	RET			;RETURN TO WHENCE WE CAME ...


; ROUTINE TO OUTPUT THE JSYS MESSAGE ON AN ERROR FROM A GTJFN OR OPENF
;
; CALL:		CALL PUTERR
; RETURNS: +1 ALWAYS

PUTERR:	MOVX T1,.PRIOU		;GET PRIMARY OUTPUT JFN
	HRLOI T2,.FHSLF		;OUR FORK, LAST ERROR CODE
	SETZM T3		;
	ERSTR			;OUTPUT ERROR STRING
	 JFCL			;IGNORE
	 JFCL			;IGNORE
	TMSG <
>				;OUTPUT NEW LINE
	RET			;RETURN TO WHENCE WE CAME ...
;ROUTINE TO CHECK THE DEVICE TO BE LOADED
;
;ACCEPTS T1/	LOAD DEVICE TYPE
;
;	CALL	CHKLDV
;
;RETURNS +1	ERROR
;        +2	SUCCESS
CHKLDV:
	SKIPE	T1		;IS IT A DTE?
	JRST	CHK200		;NO, MUST BE DN200
	CAIL	T2,0		;IS DTE # WITHIN
	CAILE	T2,3		;THE PROPER LIMITS?
	 JRST	R		;NO
	RETSKP
CHK200:
	CAIE	T2,0		;ONLY ZERO ALLOWED
	CAIN	T2,1		;OR 1
	SKIPA
	 RET			;ERROR
	RETSKP
;PUTATM - ROUTINE TO TYPE THE CONTENTS OF THE ATOM BUFFER
;
;ACCEPTS IN T1/	POINTER TO ASCIZ PREFIX STRING TO BE TYPED
;		CALL TYPATM
;RETURNS: +1 ALWAYS

TYPATM:	STKVAR <ATOMPT>
	MOVEM T1,ATOMPT		;SAVE ATOM POINTER
	CALL TSTCOL		;ISSUE NEW LINE IF NEEDED
	TMSG <? DNLOAD: >	;OUTPUT INITIAL PART OF MESSAGE
	MOVE T1,ATOMPT		;RESTORE ATOM POINTER
	PSOUT			;OUTPUT THE STRING
	TMSG < ">		;OUTPUT PUNCTUATION
	HRROI T1,ATMBFR		;GET POINTER TO THE ATOM BUFFER
	PSOUT			;OUTPUT THE TEXT ENTERED
	TMSG <"
>				;OUTPUT END OF LINE
	RET			;RETURN
SUBTTL	PARSING SUBROUTINES

; ROUTINE TO PARSE AN END-OF-COMMAND
;
; CALL:		CALL ENDCOM
; RETURNS: +1	 BAD CONFIRMATION, MESSAGE ALREADY ISSUED
;	   +2	SUCCESS, COMMAND CONFIRMED

ENDCOM:	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[FLDDB. (.CMCFM)] ;GET FUNCTION BLOCK FOR CONFIM
	COMND			;PARSE CONFIRMATION
	 erjmp cmderr		;error, go check for eof on take file
	TXNE T1,CM%NOP		;VALID END-OF-COMMAND SEEN ?
	 RET
	CALL TAKTST		;OUTPUT COMMAND LINE IF DOING TAKE COMMAND
	RETSKP			;SUCCESS, RETURN


; ROUTINE TO PARSE NOISE PHRASE
;
; CALL:	T2/ POINTER TO NOISE PHRASE
;		CALL SKPNOI
; RETURNS: +1	 ERROR, INVALID NOISE PHRASE
;	   +2 	SUCCESS, NOISE PHRASE PARSED OK

SKPNOI:	MOVE T1,[NOIFDB,,NOIFDB+1] ;SET UP TO CLEAR FUNCTION DESCRIPTOR BLOCK
	SETZM NOIFDB		;CLEAR FIRST WORD OF BLOCK
	BLT T1,NOIFDB+FDBSIZ-1	;CLEAR FUNCTION DESCRIPTOR BLOCK
	MOVX T1,.CMNOI		;GET FUNCTION TO PERFORM
	STOR T1,CM%FNC,NOIFDB	;STORE FUNCTION CODE IN FDB
	MOVEM T2,NOIFDB+.CMDAT	;STORE POINTER TO NOISE PHRASE IN FDB
	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,NOIFDB		;GET ADDRESS OF FUNCTION BLOCK
	COMND			;PARSE NOISE WORD
	 erjmp cmderr		;error, go check for eof on take file
	TXNN T1,CM%NOP		;NOISE PHRASE PARSED OK ?
	RETSKP			;YES, RETURN SUCCESS
	CALL TSTCOL		;ISSUE NEW LINE IF NEEDED
	HRROI T1,[ASCIZ/Invalid guide phrase/]
	callret typatm		;output the text entered and return
;CMDINI - ROUTINE TO INITIALIZE COMMAND STATE BLOCK AND OUTPUT PROMPT
;
;ACCEPTS IN T1/	POINTER TO ASCIZ PROMPT STRING
;		CALL CMDINI
;RETURNS: +1 ALWAYS,	WITH THE REPARSE ADDRESS SET TO THE ADDRESS OF THE
;			CALL TO CMDINI.


CMDINI:	MOVEM T1,CMDBLK+.CMRTY	;SAVE POINTER TO PROMPT STRING IN STATE BLOCK
	POP P,SAVRET		;SET UP RETURN ADR FROM CMDINI AND FROM REPARSE
	MOVEM P,SAVREP		;SAVE STACK POINTER TO BE RESET ON REPARSE
	MOVEI T1,REPARS		;GET ADDRESS OF REPARSE ROUTINE
	MOVEM T1,CMDBLK+.CMFLG	;SAVE ADDRESS OF REPARSE ROUTINE IN STATE BLOCK
	MOVEI T1,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI T2,[FLDDB. (.CMINI)] ;GET FUNCTION DESCRIPTOR BLOCK
	COMND			;INITIALIZE COMMAND SCANNER JSYS
	 ERJMP CMDERR		;ERROR, GO SEE IF END OF "TAKE FILE"
	JRST @SAVRET		;RETURN


; HERE TO PROCESS A REPARSE

REPARS:	MOVE P,SAVREP		;RESET STACK POINTER
	JRST @SAVRET		;RETURN TO CALLER OF CMDINI
;INPLDA - ROUTINE TO INPUT ONE BLOCK FROM A PDP-11 FORMAT .LDA FILE
;
;ACCEPTS IN T1/	ADDRESS OF RECORD BLOCK
;		CALL INPLDA
;RETURNS: +1	 FAILED, BAD FILE FORMAT, PREMATURE EOF, OR BAD CHECKSUM
;	  +2	SUCCESS, WITH DATA INPUT INTO RECORD BLOCK

INPLDA:	ASUBR <IBKREC,IBKSUM,IBKCTR,IBKCNT>
	STKVAR <IBKPTR>
	LOAD	T2,RBNAD	;GET NEXT LOAD ADDRESS
	STOR	T2,RBCAD	;STORE AS CURRENT LOAD ADDRESS
	LOAD	T2,RBFCT	;GET COUNT OF BYTES LEFT IN THIS RECORD
	JUMPN	T2,IBLK40	;STILL SOME TO DO IN THIS RECORD
	SETZM IBKSUM		;INITIALIZE THE CHECKSUM
	HRLI	T4,(POINT 8,)
	HRRI	T4,.RBDAT+RBLOCK	;INITIAL BYTE POINTER
	STOR	T4,RBPTR	;STORE IT

; SKIP OVER INITIAL ZERO BYTES

IBLK10:
	CALL INPBYT		;GO GET A BYTE FROM THE INPUT FILE
	 RET			;FAILED, RETURN
	JUMPE T2,IBLK10		;SKIP OVER ZERO BYTES

; THE NEXT TWO BYTES SHOULD BE A 1-BYTE FOLLOWED BY A 0-BYTE

	ADDM T2,IBKSUM		;ADD BYTE JUST INPUT TO CHECKSUM
	CAIE T2,1		;NEXT BYTE A 1-BYTE ?
	RET			;NO, BAD FILE FORMAT
	CALL INPBYT		;GO GET THE NEXT BYTE FROM THE INPUT FILE
	 RET			;FAILED, RETURN
	ADDM T2,IBKSUM		;ADD BYTE JUST INPUT TO CHECKSUM
	CAIE T2,0		;JUST READ A 0-BYTE ?
	RET			;NO, BAD FILE FORMAT

; INPUT THE BYTE COUNT (2 BYTES)

	CALL INPWRD		;GET NEXT WORD FROM FILE
	 RET			;FAILED, RETURN
	ADDM T1,IBKSUM		;UPDATE THE CHECKSUM
	MOVEM T2,IBKCNT		;SAVE BYTE COUNT
	; ..
	; ..

; READ THE LOAD OR TRANSFER ADDRESS (2 BYTES)

	CALL INPWRD		;GO GET A WORD FROM THE INPUT FILE
	 RET			;FAILED, RETURN ERROR
	ADDM T1,IBKSUM		;ADD THIS WORD TO THE CHECKSUM
	STOR T2,RBCAD	;STORE LOAD ADR IN RECORD TABLE ENTRY
	STOR T2,RBXAD	;STORE TRANSFER ADR IN RECORD TABLE ENTRY

; SET UP TO READ THE DATA BYTES FROM THE BLOCK

	MOVE T1,IBKCNT		;GET BYTE COUNT
	SUBI T1,BINHDR		;ALLOW FOR BYTES IN HEADER
	MOVEM T1,IBKCTR		;SAVE NUMBER OF DATA BYTES TO READ
	STOR T1,RBFCT	;SAVE NUMBER OF DATA BYTES IN RECORD TABLE ENTRY
	LOAD T1,RBPTR	;GET POINTER TO DESTINATION FOR DATA
	MOVEM T1,IBKPTR		;SAVE POINTER TO DESTINATION OF NEXT DATA BYTE

; READ THE DATA BYTES FROM THE BLOCK

IBLK20:	SOSGE IBKCTR		;ANOTHER BYTE TO READ ?
	JRST IBLK30		;NO, GO READ AND VERIFY BLOCK CHECKSUM
	CALL INPBYT		;GET A BYTE FROM THE FILE
	 RET			;FAILED, RETURN ERROR
	ADDM T2,IBKSUM		;UPDATE THE CHECKSUM
	IDPB T2,IBKPTR		;STORE THE BYTE IN THE RECORD BLOCK
	JRST IBLK20		;GO GET THE NEXT BYTE FROM THE FILE

; HERE TO READ AND VERIFY THE CHECKSUM AFTER READING THE DATA BYTES

IBLK30:
	CALL INPBYT		;GO GET A BYTE FROM THE FILE
	 RET			;FAILED, RETURN ERROR
	MOVN T1,IBKSUM		;GET -CHECKSUM
	LDB T1,[POINT 8,T1,35]	;GET JUST THE LOW ORDER BYTE OF CHECKSUM
	CAME T1,T2		;CHECKSUM VERIFY CORRECLTY ?
	RET			;NO, RETURN FAILURE

; HERE WHEN DONE - RETURN TO CALLER

	LOAD	T2,RBFCT	;GET TOTAL BYTES IN RECORD
IBLK40:	MOVE	T3,T2		;GET A COPY OF SAME
	CAMLE	T2,MAXMEM	;MORE THAN WILL BE ACCEPTED BY LOADER?
	MOVE	T2,MAXMEM	;YES, GIVE ONLY MAXIMUM
	SUB	T3,T2		;REMAINING BYTE COUNT
	STOR	T3,RBFCT	;REMEMBER THIS
	STOR	T2,RBCNT	;NUMBER OF BYTES TO GIVE THIS TIME
	LOAD	T3,RBCAD	;CURRENT LOAD ADDRESS
	ADD	T3,T2
	STOR	T3,RBNAD	;NEW NEXT LOAD ADDRESS
	RETSKP			;RETURN SUCCESS
; INPTSK/INPDMP - INPUT A BLOCK FROM A TASK-IMAGE OR DUMP FORMAT FILE
;
; ACCEPTS IN:
;	T1/	RECORD BLOCK ADDRESS
;
; RETURNS:
;	+1:	FAILED, I/O ERROR, INVALID FORMAT OR PREMATURE EOF
;	+2:	SUCCESS, DATA LOADED INTO RECORD BLOCK
;
INPDMP:
INPTSK:
	TRVAR <ITSREC,ITSCNT,ITSPTR>
	HRLI	T4,(POINT 8,)
	HRRI	T4,.RBDAT+RBLOCK	;INITIAL BYTE POINTER
	STOR	T4,RBPTR	;STORE IT
;
; SEE IF WE HAVE READ LABEL BLOCKS ALREADY
; SET NEW ADDRESS FOR THIS BLOCK
;
	LOAD T2,RBCAD	;GET CURRENT ADDRESS
	CAME T2,[EXP -1]	;HAS ADDRESS
	CAIL T2,777777		; BEEN SET YET?
	 SKIPA			;NO-- READ LABEL BLOCKS
	JRST ITSCBC		;YES-- JUST MOVE DATA FROM FILE
;
; SET UP BYTE COUNTS, READING LABEL BLOCKS IF NEEDED

	CALL INPCNT		;GO SET UP COUNTS
	 RET			;FAILED
;
; COMPUTE BYTE COUNT FOR THIS RECORD
;
ITSCBC:	LOAD	T2,RBNAD	;MAKE THE NEXT ADDRESS
	STOR	T2,RBCAD	;THE CURRENT LOAD ADDRESS
	LOAD T2,RBFCT	;GET REMAINING BYTE COUNT IN FILE
	MOVE T3,T2		;COPY BYTE COUNT
	CAMLE T2,MAXMEM		;MORE THAN MAX ALLOWED IN MEMORY MESSAGES?
	 MOVE T2,MAXMEM		;YES-- USE MAXIMUM
	SUB T3,T2		;COMPUTE REMAINING BYTE COUNT
	STOR T3,RBFCT	;STORE UPDATED COUNT
	MOVEM T2,ITSCNT		;REMEMBER THE COUNT
	STOR T2,RBCNT	; ALSO FOR EVERYBODY ELSE
	LOAD	T3,RBNAD	;GET OLD NEXT LOAD ADDRESS
	ADD	T2,T3		;ADD THE BYTE COUNT OF THIS LOAD
	STOR	T2,RBNAD	;REMEMBER AS NEW NEXT LOAD ADDRESS
;
; READ BYTES INTO RECORD
;
	LOAD T2,RBPTR	;GET POINTER TO DATA REGION
	MOVEM T2,ITSPTR		;SAVE THAT
;
; LOOP THROUGH THE BYTES . . .
;
ITSBLP:	SOSGE ITSCNT		;COUNT DOWN, WE DONE?
	 RETSKP			;YES-- RETURN +2 FROM INPTSK
	CALL INPBYT		;GET NEXT FILE BYTE
	 RET			;ERROR OR EOF-- RETURN NOW
	IDPB T2,ITSPTR		;STORE BYTE
	JRST ITSBLP		;LOOP FOR ALL BYTES
; INPCNT - SET UP COUNTS AND READ LABEL BLOCKS IF NEEDED
;
; ACCEPTS IN:
;
; RETURNS:
;	+1	ERROR
;	+2	SUCCESS, WITH RBFCT, RBSAD, RBNAD SET UP
;
INPCNT:
	LOAD T2,RBFTYP	;GET FILE TYPE (.FTXXX)
	CAIL T2,0		;RANGE CHECK THE FILE
	CAIL T2,FTYPLN		; TYPE CODE
	RET			;FAIL, INVALID FILE TYPE
	CALLRET @FLTYPE(T2)	;DISPATCH TO ROUTINE TO SET UP COUNTS

FLTYPE:	RET			; 0 IS ILLEGAL
	RET			; .FTLDA - SHOULD NOT BE HERE FOR LDA FILES
	INPTCT			; .FTTSK - TASK-IMAGE FILE TYPE
	INPDCT			; .FTDMP - DUMP FORMAT FILE TYPE
FTYPLN==.-FLTYPE		;SIZE OF TYPE DISPATCH TABLE


; INPTCT - INPUT COUNTS FOR A TASK-IMAGE FILE TYPE
;
; ACCEPTS:
;
; RETURNS:
;	+1	FAILED
;	+2	SUCCESS, WITH COUNTS SET UP IN RECORD BLOCK

INPTCT:
;
; READ LABEL BLOCKS
;
; SETS UP RBFCT, RBXAD, AND RBNAD
;
	MOVEI T2,L$BSA-0	;SKIP TO L$BSA
	CALL ITSSKP		; . .
	 RET			;ERROR OR END-OF-FILE
;
	CALL INPWRD		;GET BASE ADDRESS: L$BSA
	 RET			;ERROR/EOF
	STOR T2,RBNAD	;STORE BASE ADDRESS
;
	MOVEI T2,L$BLDZ-<L$BSA+2> ;SKIP TO L$BLDZ
	CALL ITSSKP		; . .
	 RET			;ERROR/EOF
;
	CALL INPWRD		;GET LOAD SIZE / 64.: L$BLSZ
	 RET			;ERROR/EOF
	LSH T2,^D6		;CONVERT LOAD SIZE TO BYTES
	STOR T2,RBFCT	;STORE LOAD SIZE AS BYTES LEFT IN FILE
;
	MOVEI T2,L$BFLG-<L$BLDZ+2> ;SKIP TO L$BFLG
	CALL ITSSKP		; . .
	 RET			;ERROR/EOF
;
	CALL INPWRD		;GET FLAGS WORD: L$BFLG
	 RET			;ERROR/EOF
	TXNN T2,TS$NHD		;TASK FILE HAVE NO HEADER: TS$NHD= 1?
	 RET			;NO-- NOT SYSTEM IMAGE
;
	MOVEI T2,L$BXFR-<L$BFLG+2> ;SKIP TO L$BXFR
	CALL ITSSKP		; . .
	 RET			;ERROR/EOF
;
	CALL INPWRD		;GET TRANSFER ADDRESS: L$BXFR
	 RET			;ERROR/EOF
	STOR T2,RBXAD	;STORE TRANSFER ADDRESS
;
	MOVEI T2,L$BHRB-<L$BXFR+2> ;SKIP TO L$BHRB
	CALL ITSSKP		; . .
	 RET			;ERROR/EOF
;
	CALL INPWRD		;GET RELATIVE BLOCK OF IMAGE: L$BHRB
	 RET			;ERROR/EOF
	LSH T2,^D9		;CONVERT TO BYTES (512. BYTES/BLOCK)
	SUBI T2,L$BHRB+2	;MINUS BYTES ALREADY READ
	CALL ITSSKP		;SKIP REMAINING LABEL BLOCKS
	 RET			;ERROR/EOF
	RETSKP			;DONE, RETURN SUCCESS
; INPDCT - ROUTINE TO SET UP THE COUNT FOR A DUMP FORMAT FILE
;
; ACCEPTS:
;
; RETURNS:
;	+1	FAILED
;	+2	SUCCESS, WITH COUNTS SET UP

INPDCT:
	SETZRO <RBNAD,RBXAD> ;INITIALIZE COUNTS
	LOAD T1,RBJFN	;GET JFN OF INPUT FILE
	MOVX T2,<2,,.FBBYV>	;TWO WORDS, BYTE SIZE WORD & FILE SIZE
	MOVX T3,T2		;PUT RESULTS INTO T2 AND T3
	GTFDB			;GET FILE DATA
	 ERJMP R		;FAILED
	LOAD T2,FB%BSZ,T2	;GET FILE BYTE SIZE
	MOVX T1,^D36		;GET # OF BITS PER WORD
	IDIV T1,T2		;COMPUTE NUMBER OF BYTES PER WORD IN FILE
	ADDI T3,-1(T1)		;FILE SIZE + BYTES/WORD -1
	IDIV T3,T1		;ROUND FILES SIZE
	IMULI T3,BPWRD		;COMPUTE NUMBER OF KL20 WORDS
	STOR T3,RBFCT	;STORE COUNT
	RETSKP			;DONE, RETURN



; ITSSKP -- SKIP SOME BYTES IN T2
;
; ACCEPTS IN:
;	T2/	COUNT OF BYTES TO SKIP
;
; RETURNS:
;	+1:	ERROR/EOF
;	+2:	SUCCESS, T1 POINTS TO RECORD BLOCK
;
ITSSKP:
	MOVEM T2,ITSCNT		;SAVE COUNT
ITSSLP:
	SOSGE ITSCNT		;BYTES LEFT?
	 RETSKP			;NO-- RETURN +2 FROM ITSSKP
	CALL INPBYT		;GET A BYTE
	 RET			;ERROR/EOF
	JRST ITSSLP		;SKIP MORE....
SUBTTL	I/O Subroutines

;INPBYT - ROUTINE TO INPUT THE NEXT BYTE FROM A PDP-11 FORMAT FILE
;
;ACCEPTS IN T1/	ADDRESS OF RECORD TABLE ENTRY
;		CALL INPBYT
;RETURNS: +1	 ERROR OR END OF FILE
;	  +2	SUCCESS, WITH BYTE IN T2

INPBYT:
	LOAD T3,RBBYT	;GET NUMBER OF NEXT BYTE IN WORD
	CAIGE T3,BPWRD		;ALREADY GOT LAST BYTE IN WORD ?
	JRST GTBT10		;NO, GO GET NEXT BYTE IN WORD

; ALL BYTES IN CURRENT WORD HAVE BEEN READ.  INPUT THE NEXT DATA WORD

	SETZRO RBBYT	;WRAP AROUND TO FIRST BYTE IN WORD
	LOAD T1,RBJFN	;GET JFN OF CURRENT INPUT FILE
	BIN			;INPUT THE NEXT WORD
	 ERJMP R		;FAILED, RETURN ERROR
	STOR T2,RBDAT	;STORE NEXT DATA WORD FROM INPUT FILE

; HERE TO ACTUALLY GET THE NEXT BYTE OF DATA

GTBT10:	LOAD T1,RBDAT	;GET CURRENT DATA WORD
	LOAD T3,RBBYT	;GET NUMBER OF NEXT BYTE TO LOAD
	LDB T2,BYTTAB(T3)	;LOAD NEXT BYTE FROM CURRENT WORD
	INCR RBBYT		;POINT TO NEXT BYTE IN WORD
	RETSKP			;RETURN WITH BYTE IN T2


; INPWRD -- INPUT A 16-BIT WORD AS TWO 8-BIT BYTES
;
; ACCEPTS IN T1/ ADDRESS OF RECORD BLOCK FOR THIS OPERATION
;
; RETURNS:
;	+1:	I/O ERROR OR END-OF-FILE
;	+2:	SUCCESS,
;			T1/	SUM OF BYTES
;			T2/	16-BIT WORD, RIGHT-JUSTIFIED
;
INPWRD:
	CALL INPBYT		;READ FIRST (LOW) BYTE
	 RET			;ERROR-- RETURN +1 FROM INPWRD
	PUSH P,T2		;SAVE LOW BYTE
	CALL INPBYT		;READ SECOND (HIGH) BYTE
	 RET			;ERROR-- RETURN +1 FROM INPWRD
	POP P,T3		;RESTORE LOW BYTE
	MOVE T1,T3		;COPY IT FOR SUM
	ADD T1,T2		;COMPUTE SUM OF BYTES TO T1
	LSH T2,^D8		;SHIFT HIGH BYTE TO BITS 15-8
	IOR T2,T3		;MUSH TOGETHER WITH LOW BYTE INTO WORD IN T2
	RETSKP			;RETURN +2 FROM INPWRD, SUM IN T1, WORD IN T2


; TABLE OF BYTE POINTERS TO GET THE "NEXT" BYTE IN PDP-11 FORMAT

BYTTAB:	POINT 8,T1,17
	POINT 8,T1,9
	POINT 8,T1,35
	POINT 8,T1,27

DBYTTB:	POINT 8,(T1),17
	POINT 8,(T1),9
	POINT 8,(T1),35
	POINT 8,(T1),27


;BYTE POINTER TABLE FOR SECONDARY LOADERS


SLDTAB:	POINT 8,(T3),15
	POINT 8,(T3),7
	POINT 8,(T3),31
	POINT 8,(T3),23
;OPNIFL - ROUTINE TO OPEN A FILE FOR INPUT
;
;ACCEPTS IN T1/	POINTER TO ASCIZ FILESPEC
;		CALL OPNIFL
;RETURNS: +1	 FAILED, GTJFN OR OPENF FAILURE
;	  +2	SUCCESS, WITH T1/ JFN OF INPUT FILE
;ENTRY OPSOPN IS FOR OPENING THE FILE DESIGNATED IN THE LOAD COMMAND SINCE
;THE COMND JSYS ALREADY GOT A JFN

OPNIFL:
	MOVE T2,T1		;COPY POINTER TO FILESPEC
	MOVX T1,GJ%OLD!GJ%SHT	;EXISTING FILE, SHORT CALL
	GTJFN			;GET A JFN FOR INPUT FILE
	 RET			;FAILED, RETURN
OPSOPN:	MOVE T2,[440000,,OF%RD]	;36-BIT BYTES, READ ACCESS ONLY
	OPENF			;OPEN THE FILE
	 JRST [	RLJFN		;FAILED, RELEASE THE JFN
		 JFCL		;IGNORE ERRORS HERE
		RET ]		;RETURN ERROR
	RETSKP

; FIND THE FILE FORMAT TYPE FROM THE FILE TYPE
FILTYP:
	STKVAR <<OPITYP,8>>
	HRRZ	T2,T1		;COPY THE JFN FOR JFNS
	HRROI T1,OPITYP		;POINT STRING POINTER TO SCRATCH
	MOVX T3,<FLD(.JSAOF,JS%TYP)> ;GET ONLY FILE TYPE
	JFNS
	 ERJMP R		;FAILED, RETURN ERROR
	MOVEI T1,FTYTAB		;POINT TO FILE TYPE TABLE
	HRROI T2,OPITYP		;POINT TO SCRATCH STRING
	TBLUK			;FIND FILE TYPE
	 ERJMP R		;FAILED, RETURN ERROR
	MOVE T3,T2		;COPY FLAGS
	HRRZ T2,(T1)		;GET TABLE ENTRY, FILE TYPE FORMAT
	TXNN T3,TL%EXM		;EXACT MATCH?
	RET			;FAIL IF UNKNOWN FILE TYPE
	RETSKP			;SUCCESS, T2/ FILE FORMAT TYPE

; FILE FORMAT TYPE TABLE FOR OPNIFL (TBLUK FORMAT)

FTYTAB:
	XWD FTYTBZ,FTYTBZ
	TB (.FTLDA,BIC)
	TB (.FTLDA,BIN)
	TB (.FTTSK,SYS)
FTYTBZ==.-FTYTAB-1
SUBTTL MOP MESSAGE CHECK ROUTINES
;CHKMOP - ROUTINE TO CHECK A MOP "REQUEST LOAD" MESSAGE AND UPDATE THE
;	    NEXT LOAD NUMBER EXPECTED.
;
;		CALL CHKMOP
;RETURNS: +1	 FAILED
;	  +2	RETRY
;         +3	SUCCESS

CHKMOP:
	MOVE	T3,RMPLNG	;GET LENGTH OF RECEIVED MOP MSG
	SUBI	T3,2		;AT LEAST FUNCTION AND LOAD # PRESENT ?
	SKIPGE	T3
	 JRST	R		;ERROR
	MOVE	T4,[POINT 8,RMPMSG] ;POINTER TO MOP MESSAGE
	ILDB	T1,T4		;GET MOP FUNCTION CODE
	CAIE	T1,.MPRQL	;REQUEST MEMORY LOAD FUNCTION ?
	 JRST	R		;ERROR
	ILDB	T1,T4		;YES, GET NEXT LOAD NUMBER REQUESTED
	MOVE	T2,LDNUM	;GET LOAD NUMBER WE LAST KNEW ABOUT
	ADDI	T2,1		;INCREMENT
	ANDI	T2,377		;MODULO 256
	CAME	T2,T1		;CORRECT LOAD NUMBER REQUESTED ?
	 JRST	R		;ERROR, RETRY MIGHT SUCCEED
	MOVEM	T2,LDNUM	;STORE UPDATED LOAD NUMBER
	SOSGE	T3		;ANOTHER BYTE IN MOP MESSAGE ?
	RETSKP		;NO, NO STATUS CODE IS PRESENT, ASSUME SUCCESS
	ILDB	T1,T4	;YES, GET THE STATUS CODE FROM THE LOADER
	CAIE	T1,.MPACK		;SUCCESS ON PREVIOUS LOAD ?
	 JRST	R		;ERROR
	RETSKP		;YES, DONE. RETURN SUCCESS.
;CHKRQP - ROUTINE TO CHECK A MOP PROGRAM REQUEST MESSAGE
;
;		CALL CHKRQP
;RETURNS: +1	 FAILED
;	  +2	SUCCESS

CHKRQP:

	MOVE	T3,RMPLNG	;GET # OF BYTES IN THE MOP MESSAGE
	SUBI	T3,4		;AT LEAST FUNCTION, DEVICE, PROGRAM & STATION ?
	SKIPGE	T3
	 JRST	R		;RETURN

; EXTRACT THE FUNCTION CODE, DEVICE TYPE, AND STATION FROM MOP MESSAGE

	MOVE	T4,[POINT 8,RMPMSG] ;POINTER TO MOP MSG
	ILDB	T1,T4		;GET MOP FUNCTION CODE
	CAIE	T1,.MPRQP	;REQUEST PROGRAM FUNCTION ?
	 JRST	R		;ERROR
	ILDB	T1,T4		;GET LOAD DEVICE TYPE (.DTXXX)
	MOVE	T2,LDTYP	;GET THE LOADING DEVICE TYPE
	XCT	[CAIE T1,.DTDMC
		 CAIE T1,.DTDTE]+1(T2)
	 RET			;WRONG LOAD DEVICE
	ILDB	T1,T4		;GET STATION ADDRESS FROM MOP MESSAGE
	CAIE	T1,1		;STATION 1 ?
	 JRST	R		;ERROR
	ILDB	T1,T4		;YES, GET PROGRAM TYPE FROM MOP MESSAGE
	STOR	T1,RBPTYP	;STORE THE REQUESTED PROGRAM TYPE
	CAIL	T1,.PTSLD	;VALID PROGRAM TYPE
	CAILE	T1,.PTOPS	; IN THE MOP PROGRAM REQUEST MESSAGE ?
	 JRST	R		;ERROR
	; ..
	; ..

; IGNORE THE SOFTWARE ID FROM THE MOP MESSAGE

	RETSKP			;DONE, RETURN SUCCESS
;CHKMMR - ROUTINE TO CHECK THE "MOP MODE RUNNING" MESSAGE
;
;		CALL	CHKMMR
;RETURNS:	+1/	FAILED
;		+2/	SUCCESS
;
CHKMMR:
	MOVE	T3,RMPLNG	;GET LENGTH OF MOP MESSAGE
	CAIE	T3,^D8		;BETTER BE EIGHT BYTES
	 RET			;ITS NOT!!
	MOVE	T1,[POINT 8,RMPMSG] ;POINTER TO THE MESSAGE
	ILDB	T4,T1		;GET THE FUNCTION CODE
	CAIE	T4,.MPMMR	;MOP MODE RUNNING?
	 RET			;NO, FAIL
	ILDB	T4,T1		;GET DEVICE TYPE
	CAIE	T4,.DTDMC	;BETTER BE A DMC11
	 RET			;ITS NOT!
	ILDB	T4,T1		;IGNORE THE MOP VERSION
	CALL	GET4		;GO GET THE MEMORY SIZE
	ILDB	T4,T1		;GET FEATURES BYTE
	TXNN	T4,MP%DMP	;DUMP SUPPORTED?
	 RET			;NO
	MOVEM	T2,LDMSIZ	;STORE TARGETS MEMORY SIZE
	RETSKP
;
;CHKMDD - CHECK MEMORY DUMP DATA MESSAGE
;
;		CALL	CHKMDD
;RETURNS	+1/ ERROR
;		+2/ SUCCESS, WITH DUMP ADDRESS IN T1
;
CHKMDD:
	MOVE	T3,RMPLNG		;LENGTH OF MESSAGE
	CAIGE	T3,5			;AT LEAST 5 BYTES?
	 RET				;NO
	MOVE	T1,[POINT 8,RMPMSG]	;BUILD POINTER TO MOP MESSAGE
	ILDB	T4,T1			;GET THE MOP FUNCTION CODE
	CAIE	T4,.MPMDD		;MEMORY DUMP DATA?
	 RET				;NO, WRONG
	CALL	GET4			;GET THE DUMP ADDRESS
	MOVE	T1,T2			;PUT IN T1
	RETSKP				;RETURN OKAY
SUBTTL MOP MESSAGE I/O ROUTINES
;MOPSND - ROUTINE TO SEND A MOP MESSAGE
;
;		CALL MOPSND
;RETURNS +1	 FAILED
;	 +2	SUCCESS
;
;

MOPSND:
	CALL	CLRBOT		;GO CLEAR THE BOOT JSYS ARGUMENT BLOCK
	MOVEI	T2,BTARG	;GET ADDRESS OF BOOT JSYS ARGUMENT BLOCK
	MOVE	T1,LDDEV	;GET THE DEVICE NUMBER
	MOVEM	T1,.BTDTE(T2)	;STORE PHYSICAL LINE NUMBER (DTE20 NUMBER)
	MOVE	T1,[POINT 8,XMPMSG] ;POINTER TO MOP MSG
	MOVEM	T1,.BTLPT(T2)	;PUT POINTER INTO BOOT JSYS ARGUMENT BLOCK
	MOVX	T1,BT%BEL	;GET "DOORBELL WANTED" FLAG
	MOVEM	T1,.BTFLG(T2)	;SAVE FLAGS IN ARGUMENT BLOCK
	MOVE	T1,XMPLNG	;MESSAGE LENGTH
	MOVEM	T1,.BTCNT(T2)	;STORE BYTE COUNT IN BOOT JSYS ARGUMENT BLOCK
	MOVEI	T1,.BTLOD	;GET "LOAD" FUNCTION CODE
	BOOT			;SEND THE DATA ACROSS THE DTE20
	 ERJMP R		;FAILED, RETURN ERROR
	RETSKP			;RETURN, DATA SENT
;MOPRCV - ROUTINE TO RECEIVE A MOP MESSAGE
;
;
;		CALL MOPRCV
;RETURNS: +1	 FAILED
;	  +2	SUCCESS
;

MOPRCV:
	CALL	CLRBOT		;GO CLEAR THE BOOT JSYS ARGUMENT BLOCK
	MOVEI	T2,BTARG	;GET ADDRESS OF BOOT JSYS ARGUMENT BLOCK
	MOVE	T1,LDDEV	;GET THE DTE/KMC # TO READ
	MOVEM	T1,.BTDTE(T2)	;STORE NUMBER OF DTE20 TO USE

; SYNCHRONIZE WITH THE BOOTSTRAP PROGRAM BY WAITING FOR A TO-20 DOORBELL

	MOVEI	T1,.BTBEL	;GET "WAIT FOR DOORBELL" FUNCTION
	BOOT			;WAIT TILL BOOTSTRAP STARTS UP
	 ERJMP R		;FAILED, RETURN ERROR

; THE PROGRAM JUST LOADED IS NOW READY TO SEND BACK A MOP MESSAGE

	MOVEI	T2,BTARG	;GET ADDRESS OF BOOT JSYS ARGUMENT BLOCK
	MOVEI	T1,MOPSIZ*4	;GET MAX NUMBER OF BYTES WE CAN RECEIVE
	MOVEM	T1,.BTCNT(T2)	;STORE BYTE COUNT
	MOVE	T1,[POINT 8,RMPMSG]	;STORE POINTER WHERE MSG TO GO
	MOVEM	T1,.BTDPT(T2)	;STORE POINTER TO WHERE MESSAGE GOES
	SETZM	.BTFLG(T2)	;CLEAR FLAGS
	MOVE	T1,LDDEV	;LINE OVER WHICH WE ARE LOADING
	MOVEM	T1,.BTDTE(T2)
	MOVEI	T1,.BTRMP	;GET "READ MOP MESSAGE" FUNCTION CODE
	BOOT			;GET A MOP MESSAGE
	 ERJMP R		;FAILED, RETURN ERROR
	MOVE	T1,.BTCNT+BTARG	;GET NUMBER OF BYTES RECEIVED
	MOVEM	T1,RMPLNG	;STORE THE LENGTH OF MOP MESSAGE
	RETSKP			;DONE, RETURN
SUBTTL ROUTINES TO BUILD MOP MESSAGES
;MAKMPL - ROUTINE TO MAKE A MOP LOAD-WITHOUT-TRANSFER-ADDRESS MESSAGE (.MPLOD)
;
;NO REQUIRED INPUTS
;		CALL MAKMPL
;RETURNS: +1	 FAILED
;	  +2	SUCCESS, THE MOP MESSAGE IS ASSEMBLED INTO BUFFER
;			MOPMSG WITH THE BYTE COUNT IN MOPLNG.


MAKMPL:

; PUT THE FUNCTION CODE, LOAD NUMBER, AND LOAD ADDRESS INTO THE MESSAGE

	CALL	CLRMOP		;GO CLEAR THE MOP MESSAGE AREA
	MOVE	T1,[POINT 8,XMPMSG] ;GET POINTER TO MOP MESSAGE
	MOVX	T2,.MPLOD	;GET MOP FUNCTION CODE
	IDPB	T2,T1		;STORE FUNCTION CODE IN MOP MESSAGE
	MOVE	T2,LDNUM	;GET THE NEXT LOAD NUMBER TO USE.
	IDPB	T2,T1		;STORE LOAD NUMBER IN MOP MESSAGE
	LOAD	T2,RBCAD	;GET THE LOAD ADDRESS
	CALL	MAK4		;GO ADD A FOUR-BYTE NUMBER TO THE MOP MESSAGE

; ADD THE MEMORY IMAGE DATA TO THE MOP MESSAGE

	LOAD	T2,RBPTR		;GET POINTER TO LOAD RECORD
	LOAD	T3,RBCNT	;GET NUMBER OF BYTES IN LOAD RECORD
	MOVE	T4,T3
	ADDI	T4,6		;COMPUTE NUMBER OF BYTES IN MOP MSG
	MOVEM	T4,XMPLNG	;SAVE IT
	MOVNS	T3		;GET -NUMBER OF BYTES IN LOAD RECORD
	SOUT			;ADD THE LOAD RECORD TO THE MOP MESSAGE
	 ERJMP R		;SHOULD NOT FAIL
	STOR	T2,RBPTR	;IN CASE WE HAVE TO RESUME FROM HERE
	RETSKP			;RETURN (POINTER IS STILL IN T1)
;MAKMLX - ROUTINE TO ASSEMBLE A MOP "LOAD  WITH TRANSFER" MESSAGE
;
;
;		CALL MAKMLP
;
;RETURNS: +1	 FAILED
;	  +2	SUCCESS, THE MOP MESSAGE IS ASSEMBLED INTO BUFFER
;			MOPMSG WITH THE BYTE COUNT IN MOPLNG.

MAKMLX:
	CALL	CLRMOP		;CLEAR MOP MESSAGE AREA
	MOVE	T1,[POINT 8,XMPMSG] ;BUILD POINTER TO MOP MSG.
	MOVEI	T2,.MPLDT	;GET LOAD-WITH-TRANSFER FUNCTION
	IDPB	T2,T1		;DEPOSIT IN MESSAGE
	MOVE	T2,LDNUM	;GET THE LOAD NUMBER
	IDPB	T2,T1		;PUT INTO MOP MESSAGE
;!!;
	LOAD 	T2,RBXAD	;GET THE TRANSFER ADDRESS
	SKIPE	LDFLG		;ARE WE DOING A DIAGNOSTIC LOAD?
	JRST	[CAIN	T2,1	;"SPECIAL" STARTING ADDRESS
		 MOVEI	T2,200	;YES,USE STATDARD DIAGNOSTIC START ADDRESS
		 CAIN	T2,0	;TRY THIS "SPECIAL" ADDRESS TOO
		 MOVEI	T2,3000	;YES, USE THIS STARDARD ADDRESS
		 TXNE	T2,1	;ODD ADDRESS OTHER THAN ONE?
		 ERRMSG(.ERR30,RET)	;YES, ERROR
		 JRST	.+1]	;GO ON
	PUSH	P,T2		;SAVE THE XFER ADDRESS
	CALL MAK4		;PUT XFER ADDRESS IN MESSAGE IN CORRECT FORMAT
	POP	P,T2		;DO TWICE SINCE SECONDARY LOADER FOR DN200
	CALL	MAK4		;DOESN'T LIKE XFER ADDR W/O LOAD ADDR BY DTE DOES
	MOVEI	T1,6		;!!;FOR DTE'S
	SKIPE	LDTYP		;!!;(LOADER BUG....)
	MOVEI	T1,12		;NUMBER OF BYTES IN MESSAGE
	MOVEM	T1,XMPLNG	;SAVE MESSAGE LENGTH
	RETSKP			;DONE
;MAKRQD - ROUTINE TO BUILD A "REQUEST DUMP" MESSAGE
;
;	CALL	MAKRQD
;RETURNS	+1/ NEVER
;		+2/ ALWAYS
;
MAKRQD:
	MOVE	T1,[POINT 8,XMPMSG] ;POINTER TO MOP MESSAGE BUFFER
	MOVEI	T2,.MPRQD	;MOP REQUEST DUMP FUNCTION CODE
	IDPB	T2,T1		;PUT INTO MESSAGE BUFFER
	LOAD	T2,RBCAD	;CURRENT DUMP ADDRESS
	CALL	MAK4		;PUT INTO MESSAGE
	LOAD	T2,RBCNT	;# BYTES TO DUMP THIS TIME
	CALL	MAKTWO		;PUT INTO MESSAGE
	MOVEI	T1,7		;# BYTES IN MESSAGE
	MOVEM	T1,XMPLNG
	RETSKP
;MAKTWO - ROUTINE TO ADD A TWO-BYTE NUMBER TO A MESSAGE
;
;ACCEPTS IN T1/	BYTE POINTER TO DESTINATION IN MESSAGE
;	    T2/	NUMBER TO BE ADDED TO MESSAGE
;		CALL MAKTWO
;RETURNS: +1 ALWAYS, WITH T1/ UPDATED BYTE POINTER TO NEXT FIELD IN MESSAGE

MAKTWO::	IDPB T2,T1		;PUT LOW ORDER BYTE INTO MESSAGE FIRST
	LSH T2,-8		;RIGHT-ADJUST HIGH ORDER BYTE OF NUMBER
	IDPB T2,T1		;DEPOSIT HIGH ORDER BYTE INTO MESSAGE NEXT
	RET			;RETURN, WITH UPDATED POINTER IN T1


;MAK4 - ROUTINE TO ADD A FOUR-BYTE NUMBER TO A MESSAGE
;
;ACCEPTS IN T1/	POINTER TO NEXT FIELD IN MESSAGE
;	    T2/	NUMBER TO BE ADDED TO THE MESSAGE
;		CALL MAK4
;RETURNS +1 ALWAYS, WITH T1/ UPDATED POINTER TO NEXT FIELD IN MESSAGE

MAK4:	ASUBR <PT4PTR,PT4NUM>

; ADD THE FIRST TWO BYTES TO THE MESSAGE

	MOVE T1,PT4PTR		;GET POINTER TO NEXT FIELD
	MOVE T2,PT4NUM		;GET NUMBER TO BE ADDED
	CALL MAKTWO		;ADD NEXT TWO BYTES TO MESSAGE

; ADD THE NEXT TWO BYTES TO THE MESSAGE

	MOVE T2,PT4NUM		;GET THE NUMBER TO BE ADDED AGAIN
	LSH T2,-^D16		;SHIFT TO POSITION THE NEXT TWO BYTES TO ADD
	CALLRET MAKTWO		;ADD NEXT TWO BYTES TO THE MESSAGE AND RETURN
;GET4 - ROUTINE TO GET A FOUR-BYTE FIELD FROM A MESSAGE
;
;ACCEPTS IN T1/ POINTER TO NEXT FIELD IN MESSAGE
;		CALL GET4
;
;RETURNS: +1 ALWAYS, WITH T1/ UPDATED POINTER TO NEXT FIELD
;			  T2/ FOUR-BYTE NUMBER FROM MESSAGE


GET4:	ASUBR	<GT4PTR,GT4NUM>
	MOVE	T1,GT4PTR	;GET MESSAGE POINTER
	MOVEI	T2,4		;NUMBER OF BYTES TO GET
	CALL	GETTWO		;GET TWO OF THEM
	 JFCL
	MOVEM	T3,GT4NUM	;SAVE THESE
	CALL	GETTWO		;GET NEXT TWO
	 JFCL
	DPB	T3,[POINT 16,GT4NUM,19] ;ADD HIGH ORDER BYTES TO NUMBER
	MOVE	T2,GT4NUM	;THIS IS THE RESULT
	RET
;
;GETTWO - ROUTINE TO GET A TWO FIELD FROM A MESSAGE
;
;ACCEPTS T1/ POINTER TO NEXT FIELD IN MESSAGE
;	 T2/ COUNT OF BYTES LEFT IN MESSAGE
;
;RETURNS: +1	FAILURE
;	  +2	WITH T1/ UPDATED BYTE POINTER
;		     T2/ UPDATED BYTE COUNTER
;		     T3/ NUMBER FROM MESSAGE
;

GETTWO:
	SOSG	T2		;ANY MORE?
	RET			;NO
	ILDB	T3,T1		;GET NEXT BYTE FROM MESSAGE
	SOSGE	T2		;ANY MORE?
	RET			;NO
	ILDB	T4,T1		;GET SECOND BYTE
	DPB	T4,[POINT 8,T3,27] ;MERGE TWO TOGETHER
	RETSKP
SUBTTL	GENERAL SUBROUTINES

; ROUTINE TO CLEAR GTJFN BLOCK USED BY COMND JSYS
;
; CALL:		CALL CLRGJF
; RETURNS: +1 ALWAYS

CLRGJF:	MOVE T1,[GJFBLK,,GJFBLK+1] ;SET UP TO CLEAR GTJFN BLOCK
	SETZM GJFBLK		;CLEAR FIRST WORD OF BLOCK
	BLT T1,GJFBLK+GJFSIZ-1	;CLEAR GTJFN BLOCK
	RET			;RETURN TO WHENCE WE CAME ...


; ROUTINE TO OUTPUT COMMAND LINE TO TERMINAL IF PROCESSING TAKE FILE
;
; CALL:		CALL TAKTST
; RETURNS: +1	ALWAYS, COMMAND LINE OUTPUT IF NEEDED

TAKTST:	HRROI T1,BUFFER		;GET POINTER TO COMMAND LINE
	SKIPE TAKFLG		;COMMANDS COMING FROM FILE ?
	PSOUT			;YES, OUTPUT COMMAND LINE
	RET			;RETURN

; ROUTINE TO CLOSE A LOADER/OPERATING SYSTEM FILE

CLSFIL:
	LOAD	T1,RBJFN	;GET THE JFN
	SKIPN	T1		;IS IT ZERO?
	RET			;NONE, JUST RETURN
	CLOSF			;CLOSE THE FILE
	 JFCL			;IGNORE ERRORS
	RET			;ALWAYS RETURN +1
;CLRMOP - ROUTINE TO CLEAR THE MOP MESSAGE AREA
;
;CALL:		CALL CLRMOP
;RETURNS: +1 ALWAYS

CLRMOP:	HRRI T1,1+XMPMSG	;GET ADDRESS OF MOP MESSAGE AREA + 1
	HRLI T1,-1(T1)		;FORM ADDRESS,,ADDRESS+1 FOR BLT
	SETZM XMPMSG		;CLEAR THE FIRST WORD OF THE AREA
	BLT T1,MOPSIZ-1+XMPMSG	;CLEAR REMAINDER OF MOP MESSAGE AREA
	RET			;RETURN

;ROUTINE TO CLEAR THE BOOT JSYS ARGUMENT BLOCK

CLRBOT:
	HRRI	T1,1+BTARG	;GET ADDRESS OF BOOT JSYS ARG BLOCK
	HRLI	T1,-1(T1)	;FORM ADDRESS,,ADDRESS+1 FOR BLT
	SETZM	BTARG		;CLEAR THE FIRST WORD
	BLT	T1,BTSIZ-1+BTARG ;CLEAR REMAINDER
	RET

;ROUTINE TO FLUSH ALL OUTSTANDING DDCMP MESSAGES ON A LINE

FLUSH:
	SKIPN	LDTYP		;DONT DO THIS FOR A DTE
	RETSKP
	CALL	CLRBOT		;CLEAR THE BOOT JSYS ARG BLOCK
	MOVE	T1,LDDEV	;GET THE LOAD/DUMP DEVICE LINE NUMBER
	MOVEM	T1,BTARG+.BTDTE ;SAVE IN ARG BLOCK
	MOVEI	T1,RMPMSG	;WHERE TO RECEIVE THE MESSAGES
	MOVEM	T1,BTARG+.BTMSG	;
	MOVEI	T1,MAXBYT	;MAXIMUM MESSAGE LENGTH WE WILL ACCEPT
	MOVEM	T1,BTARG+.BTLEN	;
	MOVEI	T1,.BTRDD	;READ FUNCTION
	MOVEI	T2,BTARG	;ADDRESS OF ARG BLOCK FOR BOOT JSYS
	BOOT
	 ERJMP	[ERRMSG(.ERR44,RET)]
	SKIPE	.BTLEN(T2)	;NO MORE, SO FINISHED
	JRST	FLUSH		;MORE THERE, GO FLUSH THEM TOO
	RETSKP			;RETURN


;ROUTINE TO SAVE ALL THE Q REGISTERS

SAVQ::	PUSH P,Q1		;SAVE THE ACS
	PUSH P,Q2
	PUSH P,Q3
	CALL 0(CX)		;RETURN TO CALLER
RESTQ:	 SKIPA			;NON-SKIP RETURN
	AOS -3(P)		;SKIP RETURN
	POP P,Q3		;RESTORE ACS
	POP P,Q2
	POP P,Q1
	RET			;AND RETURN
;CMDERR - ROUTINE TO PROCESS ERRORS ON EXECUTING A COMND JSYS
;	  IF END OF FILE REACHED ON A TAKE FILE, THE NEXT COMMAND
;	  IS SIMPLY PROCESSED.  ELSE AN ERROR MESSAGE IS ISSUED AND
;	  THE PROGRAM IS RESTARTED.
;
; CALL:		JRST CMDERR

CMDERR:	SKIPN TAKFLG		;PROCESSING A TAKE FILE ?
	JRST CMER10		;NO, GO ISSUE ERROR MESSAGE
	HRRZ T1,CMDBLK+.CMIOJ	;GET INPUT FILE JFN FOR TAKE FILE
	GTSTS			;GET THE FILE'S STATUS
	TXNN T2,GS%EOF		;AT END OF FILE ?
	JRST CMER10		;NO, GO ISSUE ERROR MESSAGE
	MOVE T1,[.PRIOU,,.PRIIN] ;YES, GET STANDARD PRIMARY JFN'S
	MOVEM T1,CMDBLK+.CMIOJ	;RESET INPUT AND OUTPUT JFN'S
	SETZM TAKFLG		;MARK THAT TAKE FILE NOT BEING PROCESSED
	JRST PARSE		;GO PROCESS NEXT COMMAND

CMER10:	CALL TSTCOL		;ISSUE NEW LINE IF NEEDED
	TMSG <? DNLOAD: Unexpected COMND JSYS error, restarting...
>				;OUTPUT MESSAGE
	JRST ENTVEC+1		;GO SIMULATE A "REENTER"

CMEREX:
;COMMAND EXECUTION ERROR.  T4 MUST BE SET UP TO HAVE THE POINTER
;TO THE ERROR MESSAGE ON ENTRY.


	CALL	TSTCOL		;CHECK IF A NEW LINE IS NEEDED.
	HRRO	T1,ERRTAB(T4)	;SET UP POINTER TO ERRORSTRING
	CALLRET	@[Z TYPATM
		  Z TYPERR](T3)

;ERROR TYPEOUT ROUTINE WHICH DOES NOT TYPE OUT THE ATOM BUFFER
TYPERR:
	PUSH	P,T1		;SAVE ERROR MESSAGE POINTER
	TMSG	<
?DNLOAD: >			;[17]
	POP	P,T1		;RESTORE IT
	PSOUT
	TMSG	<"
>
	RET


;SYSERR REPORTING ROUTINE
SYERPT:	SKIPN	LDTYP		;ONLY FOR DN22
	RET
	MOVX	T1,<BYTE (9) SEC%NL (8) 0 (1) HRC%RB (6) HRC%FM (3) HRC%HL (9) 0>
	MOVEM	T1,SYEHDR	;SET UP SYSERR HEADER BLOCK
	GTAD
	MOVEM	T1,SYEHDR+1		;TIME AND DATE
	SETZM	SYEHDR+2		;UPTIME NOT USED.
	MOVE	T1,[SIXBIT/APRID/]
	SYSGT
	MOVEM	T1,SYEHDR+3		;PROCESSOR ID
	MOVE	T1,SYERET		;ADJUST ERROR CODE
	ADDI	T1,1
	MOVEM	T1,SYERET
	MOVEI	T1,SYEHDR		;ADDRESS OF SYSERR BLOCK
	HLRO	T2,SYFNAM		;# CHARACTERS IN FILE SPC
	MOVMS	T2			;MAGNITUDE
	ADDI	T2,4			;PREPARE TO ROUND
	IDIVI	T2,5			;NUMBER OF WORDS
	ADDI	T2,<SYFSPC-SYEDAT>	;LENGTH OF SYSERR ENTRY
	ANDI	T2,777
	IORM	T2,SYEHDR		;PUT IN HEADER
	ADDI	T2,4			;INCLUDE HEADER LENGTH
	SYERR				;PUT ENTRY INTO SYSERR FILE
	 JFCL
	RET
SUBTTL CONSTANTS AND TABLES


; FDB CHAIN FOR LOAD COMMAND

LSTCHN:	FLDDB. (.CMNOI,,<TXT(LISTENING ON)>,,,<[FLDDB. (.CMDEV,,,,,<[FLDDB. (.CMCFM)]>)]>)

CMDTAB:	CMDSIZ-1,, CMDSIZ	;CURRENT,,MAX SIZE OF COMMAND TABLE
	TB (.CONVR,CONVERSE)	;CONVERSE (WITH) DEVICE-SPEC
	TB (.DLOAD,DLOAD)	;DLOAD (DTE20) N (FROM) FILE-SPEC ...
	TB (.DUMP,DUMP)		;DUMP (DTE20) N (TO) FILESPEC
	TB (.EXIT,EXIT)		;EXIT TO MONITOR
	TB (.HELP,HELP)		;OUTPUT HELP MESSAGE
	TB (.LOAD,LOAD)		;LOAD (DTE20) N (FROM) FILE-SPEC ...
	TB (.RESUM,RESUME)	;RESUME (LISTENING)
	TB (.START,START)	;START version (protocol on dte) n
	TB (.STOP,STOP)		;STOP (protocol on dte) n
	TB (.TAKE,TAKE)		;TAKE (COMMANDS FROM) FILE-SPEC ...

	CMDSIZ== .-CMDTAB

LDDVTB:	LTBSIZ-1,,LTBSIZ	;SIZE OF TABLE LISTING LOADABLE DEVICES
	TB (LDDMC,DN22)		;LOAD THE REMOTE DN200 (ON A 2020)
	TB (LDDTE,DTE)		;LOAD THE DTE (ON A 2050)
	TB (LDKMC,KMC)		;LOAD THE KMC (ON A 2020)
	TB (LDPDP,PDP11)	;**PDP** Load a DECnet node
				;**PDP** (will reload u-code of KMC11)
	LTBSIZ==.-LDDVTB

DPDVTB:	DTBSIZ-1,,DTBSIZ	;SIZE OF TABLE LISTING DUMPABLE DEVICES
	TB	(DMP200,DN22)	;DUMP A DN200
	TB	(DMPDTE,DTE)	;DUMP A DTE
	TB	(DMPKMC,KMC)	;DUMP A KMC
	DTBSIZ==.-DPDVTB

PRVRTB:	PRVRSZ-1,,PRVRSZ	;table to read protocol version
	TB	(PRD22,DN22)	;DN22
	TB	(PRD60,DN60)	;DN60
	TB	(PRMCB,MCB)	;MCB
	TB	(PR20F,RSX20F)	;RSX20F
	PRVRSZ==.-PRVRTB


PROMPT:	ASCIZ /DNLOAD>/			;PROMPT STRING

CRAMPG:	BLOCK 1000
DRAMPG:	BLOCK 1000

;ERROR CODES

;MACRO TO DEFINE THE ERROR CODES.
DEFINE ERCODS <
XLIST
ERR	.ERR0,<Illegal command to DNLOAD >
ERR	.ERR1,<Invalid device as target of load/dump>
ERR	.ERR2,<Incorrect command format>
ERR	.ERR3,<Failed to open KMC ucode file>
ERR	.ERR4,<BOOT JSYS error on KMC load>
ERR	.ERR5,<KMC load file has bad format>
ERR	.ERR6,<DLOAD a KMC is illegal>
ERR	.ERR7,<Bad device number>
ERR	.ERR10,<Unit number out of range>
ERR	.ERR11,<Failed to open secondary loader file>
ERR	.ERR12,<Invalid format for secondary loader file>
ERR	.ERR13,<Attempt to load secondary loader failed>
ERR	.ERR14,<Attempt to trigger the ROM failed>
ERR	.ERR15,<MOP reply from secondary loader failed>
ERR	.ERR16,<MOP reply from secondary loader bad>
ERR	.ERR17,<Bad file spec>
ERR	.ERR20,<Incorrect command format parsing LISTEN field>
ERR	.ERR21,<End of command expected>
ERR	.ERR22,<Specified device not a terminal>
ERR	.ERR23,<Unexpected error building a MOP message>
ERR	.ERR24,<Error transmitting MOP msg during tertiary or OPS load>
ERR	.ERR25,<Error receiving MOP msg during tertiary or OPS load>
ERR	.ERR26,<Wrong load number requested from loader during tertiary or OPS load>
ERR	.ERR27,<Failed to open tertiary loader file>
ERR	.ERR30,<Failed to open Operating System file>
ERR	.ERR31,<Bad transfer address>
ERR	.ERR32,<Not a valid extension for bootstrap file>
ERR	.ERR33,<Cannot open file for output>
ERR	.ERR34,<Error reading load file>
ERR	.ERR35,<Dump program dis not respond correctly after load>
ERR	.ERR36,<Secondary bootstrap loader/dumper too long>
ERR	.ERR37,<Error transmitting MOP msg during transfer of dump data>
ERR	.ERR40,<Expected dump record did not arrive from the FE>
ERR	.ERR41,<Dump data record from FE incorrect>
ERR	.ERR42,<Error writing dump file>
ERR	.ERR43,<Cannot initialize protocol to FE>
ERR	.ERR44,<Error flushing DDCMP buffers>
ERR	.ERR45,<Program request for unidentified program received from loader>
ERR	.ERR46,<Could not assign listening terminal line>
ERR	.ERR47,<Could not terminate protocol, continuing...>
ERR	.ERR50,<Wheel or Operator priveleges must be enabled>
ERR	.ERR51,<invalid protocol version>
LIST
>

DEFINE	ERR(A,B)<
A==:ZZ
[ASCIZ\B\]
ZZ=ZZ+1>

	ZZ=0
ERRTAB:	ERCODS			;DEFINE THE LIST OF ERROR MESSAGES
; LEVEL TABLE FOR INTERRUPT SYSTEM

LEVTAB:	RETPC1
	RETPC2
	RETPC3

; ENTRY VECTOR DEFINITION

ENTVEC:	JRST START		;MAIN ENTRY POINT
	JRST START		;REENTER ENTRY POINT
	EXP VDNLOAD		;VERSION OF DNLOAD PROGRAM


; HELP TEXT
	XLIST
HLPMSG:	ASCIZ \
DNLOAD Program

FUNCTION

	Loads programs in PDP-11 .BIN format into secondary
	Front-ends on a DECsystem-20.

	Dumps the contents of PDP-11 memory to a file in the
	TOPS-20 filesystem.

	Permits characters to be sent to the program in the PDP-11
	and allows output from the PDP-11 program to appear on
	the terminal on which DNLOAD is running.

COMMANDS

	LOAD (DTE20) n (FROM) FILE-SPEC (LISTENING ON) MCBn:
	DUMP (DTE20) n (TO) file-spec
	DLOAD (DTE20) N (FROM) FILE-SPEC (LISTENING ON) TTYN:
	RESUME (LISTENING)
	TAKE (COMMANDS FROM) file-spec
	HELP
	EXIT

OPERATION

        The LOAD command is used  to  load  standard  system
        software  into  a DN20 Front-End.  At the completion
        of loading a communications protocol initiation will
        occur  so  that the software in the PDP-11 may begin
        operation.

        The DLOAD command  is  used  to  load  a  diagnostic
        program  into  a  Front-End.  It is identical to the
        LOAD command, but  does  not  perform  the  protocol
        initiation.

        The LISTENING option on the LOAD and DLOAD  commands
        will  output  characters  from the indicated TOPS-20
        terminal line to the terminal  on  which  DNLOAD  is
        being run.

        After loading a  program  with  the  DLOAD  command,
        DNLOAD  will  accept characters from the terminal to
        be sent to the program just loaded.   All  input  to
        DNLOAD  will  be  sent  to  the  DN20.  To return to
        DNLOAD command level, enter CTRL/E (^E).  The RESUME
        command  may  be  used  to  continue listening after
        CTRL/E has been entered.

RESTRICTIONS

	WHEEL OR OPERATOR capability must be enabled to use
	the LOAD, DLOAD, OR DUMP commands.

	The terminal line used for LISTENING should be
	deassigned (using the TOPS-20 DEASSIGN command)
	when finished running DNLOAD.
\
	LIST
SUBTTL	VARIABLE DATA STORAGE

;INTERRUPT CHANNELS

RADIX 5+5

CHNTAB:
ICH000:	BLOCK 1			;ASSIGNABLE CHANNEL 0
ICH001:	BLOCK 1			;ASSIGNABLE CHANNEL 1
ICH002:	BLOCK 1			;ASSIGNABLE CHANNEL 2
ICH003:	BLOCK 1			;ASSIGNABLE CHANNEL 3
ICH004:	BLOCK 1			;ASSIGNABLE CHANNEL 4
ICH005:	BLOCK 1			;ASSIGNABLE CHANNEL 5
ICHAOV:	BLOCK 1			;ARITHMETIC OVERFLOW
ICHFOV:	BLOCK 1			;FLOATING OVERFLOW
ICH008:	BLOCK 1			;RESERVED
ICHPOV:	BLOCK 1			;PDL OVERFLOW
ICHEOF:	BLOCK 1			;END OF FILE
ICHDAE:	BLOCK 1			;DATA ERROR
ICHQTA:	BLOCK 1			;QUOTA EXCEEDED
ICH013:	BLOCK 1			;RESERVED
ICHTOD:	BLOCK 1			;TIME OF DAY (RESERVED)
ICHILI:	BLOCK 1			;ILLEG INSTRUCTION
ICHIRD:	BLOCK 1			;ILLEGAL READ
ICHIWR:	BLOCK 1			;ILLEGAL WRITE
ICHIEX:	BLOCK 1			;ILLEGAL EXECUTE (RESERVED)
ICHIFT:	BLOCK 1			;INFERIOR FORK TERMINATION
ICHMSE:	BLOCK 1			;MACHINE SIZE EXCEEDED
ICHTRU:	BLOCK 1			;TRAP TO USER (RESERVED)
ICHNXP:	BLOCK 1			;NONEXISTENT PAGE REFERENCED
ICH023:	BLOCK 1			;ASSIGNABLE CHANNEL 23
ICH024:	BLOCK 1			;ASSIGNABLE CHANNEL 24
ICH025:	BLOCK 1			;ASSIGNABLE CHANNEL 25
ICH026:	BLOCK 1			;ASSIGNABLE CHANNEL 26
ICH027:	BLOCK 1			;ASSIGNABLE CHANNEL 27
ICH028:	BLOCK 1			;ASSIGNABLE CHANNEL 28
ICH029:	BLOCK 1			;ASSIGNABLE CHANNEL 29
ICH030:	BLOCK 1			;ASSIGNABLE CHANNEL 30
ICH031:	BLOCK 1			;ASSIGNABLE CHANNEL 31
ICH032:	BLOCK 1			;ASSIGNABLE CHANNEL 32
ICH033:	BLOCK 1			;ASSIGNABLE CHANNEL 33
ICH034:	BLOCK 1			;ASSIGNABLE CHANNEL 34
ICH035:	BLOCK 1			;ASSIGNABLE CHANNEL 35

RADIX 8
SAVRET:	BLOCK 1			;RETURN ADDRESS OF CMDINI CALLER
SAVREP:	BLOCK 1			;SAVED STACK POINTER TO RESTORE ON REPARSE
RETPC1:	BLOCK 1			;RETURN PC FOR INTERRUPT LEVEL 1
RETPC2:	BLOCK 1			;RETURN PC FOR INTERRUPT LEVEL 2
RETPC3:	BLOCK 1			;RETURN PC FOR INTERRUPT LEVEL 3
CMDBLK:	BLOCK .CMGJB+5		;COMMAND STATE BLOCK FOR COMND JSYS
BUFFER:	BLOCK BUFSIZ		;INPUT TEXT STORED HERE
ATMBFR:	BLOCK ATMSIZ		;ATOM BUFFER FOR COMND JSYS
GJFBLK:	BLOCK GJFSIZ		;GTJFN BLOCK FOR COMND JSYS
PDL:	BLOCK PDLEN		;PUSH DOWN POINTER
NOIFDB:	BLOCK FDBSIZ		;FUNCTION DESCRIPTOR BLOCK FOR NOISE WORDS
NAMBUF:	BLOCK 8			;BUFFER FOR NAME OF INPUT FILE
INJFN:	BLOCK 1			;INPUT JFN FOR TAKE COMMAND
OUTJFN:	BLOCK 1			;OUTPUT JFN FOR TAKE COMMAND
TAKFLG:	BLOCK 1			;NON-ZERO IF PROCESSING INDIRECT FILE
MAXMEM:	BLOCK	1		;MAX # OF BYTES IN MOP MSG(LOADER DEPENDENT)
RBLOCK:	BLOCK MAXBSZ
INPJFN:	BLOCK 1			;JFN OF SECONDARY BOOTSTRAP LOAD FILE
DATWRD:	BLOCK 1			;CURRENT DATA WORD
TXTBLK:	BLOCK TXTSIZ		;TEXTI BLOCK
DCOMND:	BLOCK DCOSIZ		;DIAG COMMAND TEXT BLOCK
BYTNUM:	BLOCK 1			;NUMBER OF NEXT BYTE TO INPUT
PROCES:	BLOCK 1			;HANDLE OF PROCESS LISTENING ON LINE
LINJFN:	BLOCK 1			;DESIGNATOR OF LINE BEING LISTENED TO
STRING:	BLOCK 8			;TEMPORARY STRING AREA
BTARG:	BLOCK BTSIZ
MOPSIZ==1000
XMPLNG:	BLOCK 1			;MOP MESSAGE LENGTH
RMPLNG: BLOCK 1			;RECEIVE MOP MSG LENGTH
XMPMSG:	BLOCK MOPSIZ
RMPMSG: BLOCK MOPSIZ			;RECEIVE MOP MSG AREA
LDTYP:	BLOCK 1		;	LOAD DEVICE TYPE
LDTPDP:	BLOCK 1		;**PDP** Loading DECnet node if set.
LDDEV:	BLOCK 1			;LOAD DEVICE #
PTYPE:	.VND60			;protocol version to start
LDFIL:	BLOCK 1			;POINTER TO FILE-SPEC TO LOAD
LDLIN:	BLOCK 1			;LINE TO LISTEN ON
LDNUM:	BLOCK 1			;LOAD NUMBER
LDFLG:	BLOCK 1			;FLAG
PROFLG:	BLOCK	1		;flag for start/stop protocol
LDMSIZ:	BLOCK 1			;MEMORY SIZE OF LOAD/DUMP TARGET
LDRTRY:	BLOCK 1		;CURRENT RETRY COUNTER
SYEHDR:	BLOCK 4		;SYSERR HEADER BLOCK
SYEDAT:
SYETAR:	-4,,5			;POINTER TO TARGET NAME
SYESER:	-6,,6			;POINTER TO SERVER NAME
SYELIN:	-7,,10			;POINTER TO LINE NUMBER
SYFNAM:	0,,12			;FILE NAME FOR SYSERR
SYERET:	BLOCK 1		;RETURN CODE
	ASCII/DN22/
	ASCII/DNLOAD/
SYEDEV:	ASCII/KDP_0_0/
SYFSPC:	BLOCK	50
PAT:	BLOCK 100

	END <3,,ENTVEC>