Google
 

Trailing-Edge - PDP-10 Archives - BB-F493Z-DD_1986 - 10,7/bootdx.mac
There are 7 other files named bootdx.mac in the archive. Click here to see a list.
TITLE	BOOTDX TO BOOTSTRAP THE MICRO HIDDEN IN THE DX10 OR DX20
SUBTTL	T.HESS/TAH/EGF/TW/GMU	23-AUG-79

	.TEXT "/SEG:LOW REL:HELPER"



;COPYRIGHT (C) 1974,1975,1976,1977,1978,1979 BY
;DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;
;
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY  OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF THE  SOFTWARE  IS  HEREBY
;TRANSFERRED.
;
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT  NOTICE
;AND  SHOULD  NOT  BE  CONSTRUED  AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY  OF  ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.

.EDTR==0	;LAST EDITOR
.MAJV==3	;MAJOR VERSION #
.MINV==1	;MINOR VERSION
.EDIT==24	;EDIT #
%%BTDX==BYTE (3).EDTR(9).MAJV(6).MINV(18).EDIT

;PROGRAM WHICH BOOTSTRAPS AND DUMPS PDP-8A'S INSIDE THE
;DX10 PROGRAMMABLE DATA CHANNEL.
; OR BOOTS AND DUMPS THE MICRO-PROCESSOR INSIDE THE DX20

;LOAD INSTRUCTIONS
;	.LOAD BOOTDX.MAC, %"SEG:LOW" REL:HELPER.REL

; Edit history:
;
; 22	BCM	10-Oct-80	SPR #10-29970
;	put in check for existence of DX10
; 23	BCM	4-May-81	SPR #10-
;	move the check for edit 22, 3 lines down
; 24	SMW	9-4-84
;	Ignore KLIPA's and KLINI's, they aren't really RH20's
;
	LOC	137
	%%BTDX
	RELOC

	SALL
;PERMANANT REGISTER ASSIGNMENT


;MACRO TO GENERATE CODE FOR SETTING UP T2,T3 FOR WTREG/WTRGX

DEFINE PREWT(X)
	<SETZ T2,		;;SET T2 TO 0
	MOVEI	T3,X		;;GET REGISTER NUMBER IN T3
	>;END OF PREWT

;MISCELLANEOUS DEFINITION

PDLTH=20			;STACK DEPTH FOR SUBROUTINE CALLS
BUFLEN=^D20			;BUFFER LENGTH FOR OPERATOR COMMAND

;MAGIC ADR AND VALUE DEFINITION

MAGICA==11			;ADDRESS THAT THE STANDALONE AND
				; USER MODE BOOTSTRAPS MUST PUT A
				; MAGIC VALUE IN AS THE MONITOR CHECKS
				; THE MAGIC VALUE DURING INITIALIZATION.
MAGICV==42562			;THE MAGIC VALUE
;RH20 CONI/CONO BITS

;CONI (RH)

CI.BPE==1B18			;DATA BUS PARITY ERROR
CI.EXC==1B19			;EXCEPTION
CI.LWE==1B20			;LONG WORD COUNT ERROR
CI.SWE==1B21			;SHORT WORD  COUNT ERROR
CI.MBE==1B22			;MBOX ERROR
CI.DRE==1B23			;DRIVE RESPONSE ERROR
CI.RAE==1B24			;REGISTER ACCESS ERROR
CI.MBH==1B25			;MBOX HALTED
CI.OVR==1B26			;DATA OVERRUN
CI.MEN==1B27			;MASSBUS ENABLE
CI.ATN==1B28			;DRIVE ATTENTION
CI.2RF==1B29			;SECONDARY COMMAND REGISTER FULL
CI.ATE==1B30			;ATTENTION EBABLE
CI.1RF==1B31			;PRIMARY COMMAND REGISTER FULL
CI.DON==1B32			;CHANNEL DONE
CI.PIA==7			;PRIORITY ASSIGNMENT
CI.ERR==555000			;BITS THAT CAUSE ERRORS

;CONO

CO.RAE==1B24			;CLEAR REGISTER ACCESS ERROR
CO.RST==1B25			;CONTROLLER RESET
CO.XFR==1B26			;CLEAR TRANSFER ERROR
CO.MEN==1B27			;MASSBUS ENABLE
CO.RCL==1B28			;RESET MBOX COMMAND LIST POINTER
CO.DEL==1B29			;DELETE SECONDARY COMMAN
CO.ATE==1B30			;ENABLE ATTENTION INTERRUPTS
CO.STP==1B31			;STOP CURRENT COMMAND
CO.DON==1B32			;CLEAR DONE
CO.CLR==005010			;CLEAR BITS THAT CAUSE INTERRUPTS

SUBTTL PARAMETERS

;DX20 REGISTERS
DXCTR==0			;CONTROL REGISTER
DXSTR==1			;STATUS REGISTER
DXERR==2			;ERROR REGISTER
DXMTR==3			;MAINTENNANCE REGISTER
DXASR==4			;ATTENTION SUMMARY REGISTER
DXDTR==6			;DRIVE TYPE AND HARDWARE VERSION REG.
DXDR0==30			;DIAGNOSTIC REGISTER
				; IR FOR MICROPROCESSOR
DXDR1==31			;DIAGNOSTIC REGISTER
DXDR5==35			;DIAGNOSTIC REGISTER 5
DXDR7==37			;DIAGNOSTIC REGISTER 7

;DXMTR BITS & FIELDS
MP.SC==1B31			;SINGLE CYCLE
WR.EP==1B32			;WRITE SINGLE PARITY
MP.STA==1B33			;MP START
DX.RST==1B34			;BIT FOR RESET DX20

;DXDR1 BITS & FIELDS
IR.EN==1B20			;ENABLE IR LOAD FROM MICRO-STORE
MS.EN==1B21			;ENABLE MICRO-STORE LOAD FROM IR
PC.EN==1B22			;ALLOW LOAD/WRITE OF PC
PC.AI==1B23			;ENABLE PC AUTO-INCREMENTING

DX.PC=7777B35			;MASK FOR THE PC

;DXDR7 BITS & FIELDS
IR.PER==1B22			;IR PARITY ERROR

;COMMON DATAO BITS & FIELDS
DO.RS:	POINT	6,T2,5		;REGISTER SELECT FIELD
DO.LR==1B6			;LOAD REGISTER ENABLE
DO.DRE==1B9			;DISABLE RAE STOP

;COMMON DATAI BITS
DI.CPE==1B8			;CONTROL BUS PARITY ERROR
DI.TRA==1B10			;TRA (MASSBUS SIGNAL)

;MASS BUS DEVICE TYPES
TY.RP4==020			;RP04 DRIVE TYPE
TY.RS4==001			;RS04 DRIVE TYPE
TY.TML==010			;LOWEST TM02 TYPE
TY.TMH==017			;HIGHEST TM02 TYPE
TY.DX2==60			;DX20/TX02 DRIVE TYPE***(=050060)
				; VERSION # IS 100****(100017)
TY.RP2==61			;DX20/RP20 DRIVE TYPE (010061)
				; UCODE VERSION 200

;FIELD DEFINITION FOR DX20 REGISTERS
DT.TYP:	POINT	9,T1,35		;DRIVE-TYPE FIELD IN REGISTER
ED.NUM:	POINT	10,Q1,35	;EDIT NUMBER
VR.NUM:	POINT	6,Q1,25		;VERSION NUMBER
SUBTTL	DEFINITIONS

;DEVICE CODES

PDC==220		;FIRST DX10
PDC2==224		;2ND DX10

;DX10 CONO AND CONI BITS

RUNIND==(1B17)		;RUN INDICATOR
MPERR==1B26		;MICRO-PROCESSOR ERROR
CLRERR==001700		;CLEARS ALL ERRORS
PIMASK==774007		;MASK FOR INFO TO SAVE

;DX10 REGISTER SELECTION CODES

RSEL==(1B17)		;SELECT REGISTER
MPCTL==4		;CONTROLL AND MEMORY DATA
MPADR==5		;ADDRESS
FR==14			;FEATURE REGISTER

;BITS IN CTL REGISTER

MPSS==1B18		;SINGLE STEP SWITCH
MPHALT==1B19		;HALT SWITCH
MPCONT==1B20		;CONTINUE SWITCH
ENEXM==1B22		;ENABLE EXAMINE
ENDEP==1B23		;ENABLE DEPOSIT

DXCLR==1B16		;DX10 MASTER CLEAR

HLTINS==7402		;PDP-8 HALT INSTR

;DEFINITIONS FROM C.MAC

SP.CR0==1		;RUN ON CPU0 ONLY
.STCPU==14		;SET CPU SPECIFICATION
;USELESS MACROS

	DEFINE	TELLCR	(STRING)<
	OUTSTR	[ASCIZ	\" STRING
\]
		>

	DEFINE	WARNCR	(STRING)<
	OUTSTR	[ASCIZ	\% STRING
\]
		>

	DEFINE	ERROR	(STRING)<
	XLIST
	JRST	[OUTSTR	[ASCIZ \? STRING
\]
		JRST	EXITX]
	LIST>

	DEFINE	USEROR	(STRING)<
	XLIST
	JRST	[OUTSTR	[ASCIZ \? STRING
\]
		JRST	STARTE]
	LIST>

	DEFINE	RETURN <
	XLIST
	POPJ	P,
	LIST>
;PARAMETERS

CHI==1			;INPUT CHANNEL
CHIMOD==10		;INPUT MODE (IMAGE)
CHXMOD==0		;INPUT MODE OF A8 FILE
CHO==2			;OUTPUT CHANNEL FOR DUMPS
CHOMOD==0		;OUTPUT MODE (ASCII)

PDSIZ==20		;PDL SIZE


;AC'S

F==0
T1=1
T2=2
T3=3
T4=4

P1=5
P2=6
P3=7
P4=10
WC==11		;WORD COUNT FOR A8 FILES
RHNUM=12	;THE RH20 NUMBER		\ KEEP
DRVNUM=13	;THE DRIVE NUMBER FOR THE RH20	/ TOGETHER
Q1=14
Q2=15

W=16		;PNTR TO IOWD BASE
CX==16
P=17		;PUSH DOWN PNTR

;BITS IN F
DR.CHK==1B35			;CHECKING FOR A DX20
DXFND==1B34			;FOUND 1 DX20 ALREADY

IFNDEF V.CLR,<V.CLR==7777>	;END OF AREA TO CLEAR
IFNDEF V.DUMP,<V.DUMP==0>	;START OF DUMP
IFNDEF V.END,<V.END==7777>	;END OF AREA TO DUMP+1
IFNDEF V.TYPE,<V.TYPE==TY.DX2>	;DEFAULT DRIVE TYPE
IFNDEF V.STRT,<V.STRT==200>	;START ADDRS
IFNDEF V.DX2T,<V.DX2T==TX2OFS> ;DEFAULT OFFSET INTO TABLES OF TYPE
			       ;OF CONTROLLER ON DX20 IF NO TYPE IS
			       ;EXPLICITLY GIVEN (TX02)
IFNDEF V.DFLT,<V.DFLT==-1>	;SET TO -1 IF /DX10 IS TO BE THE
				;DEFAULT SWITCH, 0 IF /DX20 IS TO
				;BE THE DEFAULT
	SUBTTL	LOAD PROGRAM

STARTE:	CLRBFI			;CLEAR TTY INPUT IF ERROR
START:	RESET
	SETZB	F,FWAZER	;CLEAR STORAGE
	MOVE	T1,[FWAZER,,FWAZER+1]
	BLT	T1,LWAZER
	SETOM	FWAONE		;PRESET SWITCH ANSWERS TO -1
	MOVE	T1,[FWAONE,,FWAONE+1]
	BLT	T1,LWAONE
START2:	JSP	T2,[MOVE P,[IOWD PDSIZ,PDLST]
		    MOVEI T1,TTOCH
		    MOVEM T1,OCHLOC	;SET UP TTY OUTPUT
		    JRST @T2]

	PUSHJ	P,GETCOM	;GO GET COMMAND
	JUMPL	RHNUM,START3
	PUSHJ	P,SETCPU	;SET CPU ONLY ON CPU SPECIFIED
	MOVEI	T1,CCINT	;SET UP ^C INTERCEPT
	HRRM	T1,.JBINT##	;SAVE IN CORRECT PLACE
	SETZB	T1,CCINTP	;ZAP
	TRPSET	T1,		;GET GOOD PRIVS
	 ERROR <TRPSET failed>
	SKIPGE	DRVNUM		;UNIT SPECIFIED?
	PUSHJ	P,LOKDX		;NO, FIND THE DEFAULT
	PUSHJ	P,TESDSW	;MAKE SURE WE HAVE A VALID DX20
	SETOM	A.CHL		;MAKE LATER CODE HAPPY
				;FALL INTO NEXT PAGE
START3:	RESET			;RECLAIM SPACE IF RE-STARTING
	XCT	START2		;SET UP PUSH DOWN LIST
	MOVEI	W,PDCBAS	;ASSUME CHL 0
	SKIPGE	T1,A.CHL	;USER SPECIFIED?
	JRST	START4		;NO - USE DEFAULT
	CAILE	T1,1		;IN RANGE?
	  USEROR Illegal DX10 channel number
	MOVE	W,[PDCBAS
		   PDC2BS](T1)

START4:	SKIPE	NODEF		;DID USER SPECIFY SWITCHES?
	JRST	STRT4A		;YES (S)HE DID...
	MOVEI	T1,V.STRT	;USE /START AS THE DEFAULT
	MOVEM	T1,A.STRT	;SET UP DEFAULT VALUE
	JRST	STRT4B		;JUMP OVER SWITCH CHECK
STRT4A:	SETZM	NODEF		;CLEAR DEFAULT SWITCH
	SKIPGE	A.DUMP		;SEE IF /DUMP
	SKIPL	A.END		;OR IF /END
	JRST	DODUMP		;GO DO DUMP
	SKIPL	A.STRT		;SEE IF /START
	SKIPGE	A.LOAD		;AND /LOAD
	JRST	.+2		;NO--OK
	USEROR	Can't do both /LOAD and /START

	SKIPL	A.CLR		;SEE IF /CLEAR
	JRST	[SKIPGE	A.LOAD	;YES--SEE IF /LOAD
		 SKIPL	A.STRT	; OR /START
		 JRST	.+1	;YES--DO BOTH
		 JRST	STRTLD]	;NO--GO START 11
STRT4B:	SKIPN	T2,DEV		;IS DEVICE NULL
	MOVSI	T2,'SYS'	;YES - THEN USE SYS
	MOVEI	T1,CHXMOD	;SET UP MODE
	MOVEI	T3,INHDR	;POINT TO RING HEADER
	OPEN	CHI,T1		;OPEN CHL
	  USEROR	Can't OPEN the input device

			;;;; FALIN TO NEXT PAGE
	JUMPL	RHNUM,START5
	MOVE	T2,A.DX20	;GET TYPE OF DX20
	MOVE	T2,FILTAB(T2)	;GET DEFAULT FILENAME FOR CONTROLLER
	MOVSI	T3,'ADX'
	JRST	START6
START5:	MOVE	T2,['DXMPA ']	;DEFAULT FOR DX10 IS DXMPA.A8
	MOVSI	T3,'A8 '
START6:	SKIPN	T1,NAME		;GET FILE NAME
	MOVE	T1,T2		;USE DEFAULT
	SKIPN	T2,EXT		;EXTENSION
	MOVE	T2,T3
	TRZ	T2,-1		;CLEAR NULL FLAG
RELOOK:	MOVEI	T3,0		;CLEAR WORD
	MOVE	T4,DIRECT	;GET DIRECTORY
	DMOVEM	T1,FILNAM	;SAVE NAME FOR VERIFY
	LOOKUP	CHI,T1		;LOOKUP FILE
	  JRST LUKAGN		;SEE IF MORE TRIES
	INBUF	CHI,0		;DEFAULT BUFFERS

STRTLD:	PUSHJ	P,RESET8	;GO RESET '8
	SKIPGE 	A.CLR		;SEE IF /CLEAR
	JRST	[MOVEI T1,V.CLR	;NO - DO DEFAULT
		 MOVEM T1,A.CLR
		 JRST .+1]
	PUSHJ	P,CLEAR		;TRY TO CLEAR '8
	SKIPGE	VERERR
	ERROR	<Error while clearing memory.>
	SKIPGE	A.LOAD		;WANT TO LOAD
	SKIPL	A.STRT		; OR START
	SKIPA			;YES - GO ON
	JRST	[PUSHJ P,RESTOR	;NO - JUST /CLEAR I GUESS
		 JRST START]	;RESTART
	SETZM	VERERR		;CLEAR VERIFY ERROR FLAG
	JUMPGE	RHNUM,LOAD20
	TELLCR	DX10 loading

	MOVE	T1,[MEM8,,MEM8+1]
	MOVE	T2,[BYTE (12)HLTINS,HLTINS,HLTINS]
	MOVEM	T2,MEM8		;INIT TO ALL HALTS
	BLT	T1,MEM8+^D4096/3
	PUSHJ	P,CHKLFT	;SEE WHAT TYPE OF FILE
	SKIPE	A8FLG		;BIN OR A8
	JRST	STRTA8		;A8 - START LOADING
	JRST	STRTL1		;BIN - LOAD IT

LUKAGN:	SKIPE	EXT		;CHECK ARG
	JRST	LUKERR
	CAMN	T2,[SIXBIT /A8/]	;FIRST DEFAULT
	JRST	[MOVSI T2,'BIN'	;TRY .BIN
		 JRST RELOOK]
	TLZE	T2,-1		;DEFAULT OR NULL
	JUMPE	T2,RELOOK	;TRY NULL
LUKERR:	 USEROR	LOOKUP failed
STRTL1:	PUSHJ	P,GETBYT	;GET A BYTE
	JUMPE	P1,STRTL1	;SKIP ZEROES

	CAIE	P1,200		;VALID LEADER?
	ERROR	<Cannot find leader>

STRTL2:	PUSHJ	P,GETWRD	;FETCH WORD
	CAIN	P1,20000	;IS THIS LEADER
	JRST	STRTL2		;YES - SKIP IT
	TRZN	P1,10000	;CHECK FOR ADDRESS
	ERROR	<First word not an address>

	SETZM	CHKSUM		;CLEAR CKSUM & FLAG
	SETZM	VERERR		;...
	SETZM	BINFLG		;BIN/RIM TAPE FLAG
LDBINA:	PUSHJ	P,LOADA		;GET ADDRESS
	ADDM	P2,CHKSUM	;ADD TO CHECKSUM
	PUSHJ	P,GETWRD	;GET NEXT WORD

LOAD1:	CAIN	P1,20000	;TRAILER?
	JRST	LOADV		;YES - GO VERIFY
	TRZE	P1,10000	;ADDRESS?
	JRST	LDBINA		;YES - HANDLE IT
	PUSH	P,P2		;SAVE PARTIAL CKSUM
	PUSH	P,P1		;SAVE WORD
	PUSHJ	P,GETWRD	;PEEK AHEAD
	TRNN	P1,30000	;2ND DATA WORD?
	SETOM	BINFLG		;YES - SAY ITS A BIN TAPE
	TRNN	P1,20000	;TRAILER?
	JRST	LDBINW		;NO - LOAD IT
	SKIPGE	BINFLG		;BIN/RIM?
	JRST	LDBINC		;BIN TAPE CHECK CHECKSUM
LDBINW:	EXCH	P1,0(P)		;SAVE P1 GET WORD
	PUSHJ	P,LOADW		;LOAD IT
	MOVE	T1,-1(P)	;RESTORE CHECKSUM
	ADDM	T1,CHKSUM	;ACCUMULATE
	POP	P,P1		;RESTORE P1
	POP	P,T1		;PRUNE PDL
	JRST	LOAD1		;LOOP BACK FOR MORE

;HERE TO CHECK CKSUM FOR BINARY FORMAT TAPES

LDBINC:	POP	P,P1		;THIS MUST BE THE CKSUM
	POP	P,P2		;CLEAN PDL
	MOVE	T1,CHKSUM	;GET OUR CHECKSUM
	ANDI	T1,7777		;TRIM TO 12 BITS
	ANDI	P1,7777		;LIKEWISE FILE COPY
	CAME	P1,T1		;TA-DA
	ERROR	<Checksum does not match>

;HERE TO VERIFY CORE IMAGE

LOADV:	MOVEI	P1,0		;INITIAL ADDRESS
	MOVE	P2,[POINT 12,MEM8]	;POINT TO INTERNAL COPY
	PUSHJ	P,EXAM8		;SET FOR SUPER-EXAMINE
	  JRST	LOADV1		;T1 HAS CONTENTS
	JRST	LDDONE		;ALL DONE - DO WRAP UP

LOADV1:	ILDB	P1,P2		;GET COPY
	CAMN	P1,T1		;???
	JRST	LOADV2		;SO FAR SO GOOD
	PUSH	P,T1		;SAVE WHAT WE SAW
	SETOM	VERERR		;SAY WE LOST
	OUTSTR	[ASCIZ /? Verify error at /]
	MOVE	T1,ADDRES	;TELL HIM WHERE
	PUSHJ	P,L4OCT
	OUTSTR	[ASCIZ /  ,has /]
	POP	P,T1		;GET IT BACK
	PUSHJ	P,L4OCT		;TELL THE BAD NEWS
	OUTSTR	[ASCIZ /  ,should have /]
	MOVE	T1,P1		;REAL STUFF
	PUSHJ	P,L4OCT		;SORRY 'BOUT THAT
	OUTSTR	[BYTE (7)15,12]	;CRLF
LOADV2:	AOS	T1,ADDRES	;ADVANCE TO NEXT LOC
	CAIG	T1,7777		;FINISHED?
RSKP:
CPOPJ1:	AOS	0(P)		;SAY GO ON
	POPJ	P,		;CRAZY WAY OUT

;ALL DONE CHECK ERRORS AND START '8 IF NECESSARY

LDDONE:	SKIPE	VERERR		;SEE IF OK
	ERROR	<Verify error>
	PUSHJ	P,LMAJIK	;LOAD CONST
	PUSHJ	P,FETCNF	;GET CONFIG INFO
	SKIPGE	P2,A.STRT	;LOOK FOR STARTING ADDRS
	MOVE	P2,A.LOAD	;...
	SKIPG	P2		;ONE SPECIFIED?
	MOVEI	P2,V.STRT	;USE DEFAULT
	SKIPL	A.LOAD		;LOAD ONLY?
	MOVEI	P2,0		;YEP
	SKIPE	P2		;SHOULD WE START IT
	PUSHJ	P,START8	;YES - TRY TO
	SKIPN	P2		;GIVE CORRECT MESSAGE
	TELLCR	DX10 loaded.
	SKIPE	P2
	TELLCR	DX10 started.
	CLOSE	CHI,		;TERMINATE INPUT CHL
	RELEAS	CHI,
	PUSHJ	P,PNTCNF	;PRINT CONFIG INFO
	JRST	GOHOME		;WHEW
;ROUTINE TO LOAD ADDRESS IN P1 INTO ADRS REG

LOADA:	MOVEM	P1,ADDRES	;SAVE ADDRESS
	MOVE	T1,[RSEL,,MPADR]
	XCT	PDCDTO(W)	;SELECT ADRS REG
	MOVE	T1,ADDRES
	XCT	PDCDTO(W)	;LOAD ADDRESS
	PUSH	P,P2		;DON'T CLOBBER P2
	IDIVI	P1,3		;COMPUTE ADDRS INTO MEM8
	ADD	P1,MPNTR(P2)	;GET B.P.
	MOVEM	P1,APNTR	;SAVE IT
	POP	P,P2
	POPJ	P,		;RETURN

;ROUTINE TO LOAD PDP-8 WORD IN P1

LOADW:	MOVE	T1,[RSEL,,MPCTL]
	XCT	PDCDTO(W)	;SELECT CONTROL REG
	MOVE	T1,P1		;GET WORD
	IORI	T1,ENDEP	;ENABLE DEP
	XCT	PDCDTO(W)	;DEPOSIT WORD IN MEM
	MOVE	T1,P1		;GET WORD AGAIN
	IDPB	T1,APNTR	;STASH IN MEM8
	AOS	T1,ADDRES	;INCR ADDRESS
	CAIE	T1,10000	;DON'T CHECK THIS
	PUSHJ	P,CKCPMA	;CHECK HDWRE ALSO AND EXIT
	POPJ	P,		;RETURN
;ROUTINE TO LOAD A8 FILES

STRTA8:	SETZM	CHKSUM		;CLEAR THIS
	SETZM	VERERR
LDA8WC:	PUSHJ	P,WCREAD	;GET WORD COUNT IN WC
	JUMPE	P1,LOADV	;DONE IF ZERO
	MOVE	WC,P1
	PUSHJ	P,WDREAD	;GET DATA WORD
	PUSHJ	P,LOADA		;LOAD ADDRESS
LDA8D:	PUSHJ	P,WDREAD	;GET WORD
	MOVE	T1,P1		;SET UP DATA WORD
	PUSHJ	P,LOADW		;LOAD IT
	SOJG	WC,LDA8D	;LOOP THROUGH ALL WORDS
	PUSHJ	P,CHREAD	;READ AND VERIFY CHECKSUM
	JRST	LDA8WC		;GET NEXT RECORD
;ROUTINE TO READ THE CHECKSUM FROM FILE AND THE CRLF
;CHECK THAT CHECKSUM IS CORRECT

CHREAD:	PUSHJ	P,GET2W		;GET A WORD
	CAIE	P2,15		;TERMINATOR BETTER BE CR
	ERROR	<End-of-line missing>
	ADD	P1,CHKSUM	;ADD COMPUTED CHECKSUM
	ANDI	P1,7777		;CHECKIT
	JUMPN	P1,[ERROR <Checksums do not agree>]
	PUSHJ	P,GETC		;GET LF
	CAIE	P1,12		;DOUBLE CHECK CRLF
	ERROR	<End-of-line missing>
	POPJ	P,		;RETURN
;ROUTINE TO DO MEMORY EXAMINES
;P1 HAS ADDRS TO START AT
	
;RETURN WITH CPOPJ TO STOP CYCLE/ CPOPJ1 TO DO NEXT EXAMINE

EXAM8:	MOVE	T1,[RSEL,,MPADR]
	XCT	PDCDTO(W)	;SELECT ADDRS REG
	MOVE	T1,P1		;STARTING ADDRESS
	XCT	PDCDTO(W)	;SET IT
	MOVEM	P1,ADDRES	;SAVE ADDRS
EXAM8N:	MOVE	T1,[RSEL,,MPCTL]
	XCT	PDCDTO(W)	;SELECT CONTROLL
	MOVEI	T1,ENEXM	;ENABLE EXAMINE
	XCT	PDCDTO(W)	;...
	XCT	PDCDTI(W)	;READ CONTENTS
	ANDI	T1,7777		;JUST THE CONTENTS
	PUSHJ	P,@0(P)		;CALL CALLER
	  JRST	CPOPJ1		;HE IS THROUGH
	MOVE	T1,ADDRES	;GET INCREMENTED ADDRES
	PUSHJ	P,CKCPMA	;CHECK AUTO INCR
	JRST	EXAM8N		;GET NEXT ITEM

FETCNF:	MOVE	T1,[RSEL,,FR]
	XCT	PDCDTO(W)	;FEATURE REGISTER
	XCT	PDCDTI(W)	;READ IT
	MOVEM	T1,FEATUR	;FEATURES?
	MOVEI	P1,3		;READ LOCATION 3
	PUSHJ	P,EXAM8		;...
	  POPJ	P,
	MOVEM	T1,VERMP	;VERSION #
	AOS	P1,ADDRES	;NEXT LOC
	PUSHJ	P,EXAM8		;DO IT THE HARD WAY
	  POPJ	P,		;THIS IS WIERD
	MOVEM	T1,EDTMP	;SAVE EDIT #
	POPJ	P,		;RETURN

LMAJIK:	MOVE	T1,[RSEL,,MPADR]
	XCT	PDCDTO(W)	;SELECT ADDRS
	MOVEI	T1,17		;SECRET LOC
	XCT	PDCDTO(W)	;...
	MOVE	T1,[RSEL,,MPCTL]
	XCT	PDCDTO(W)	;SELECT CTL REG
	MOVEI	T1,4756!ENDEP	;THIS IS IT FOLKS!!!!
	XCT	PDCDTO(W)	;MAJIK NOW LOADER
	POPJ	P,		;RETURN
SUBTTL	DUMP PROGRAM

DODUMP:	SKIPL	RHNUM		;THIS A DX20?
	USEROR	<Can't /DUMP a DX20>
	SKIPGE	A.LOAD		;SEE IF /LOAD
	SKIPL	A.STRT		;OR IF /START
	USEROR	Can't /LOAD and /DUMP at the same time
	SKIPL	A.CLR		;SEE IF /CLEAR
	USEROR	Can't /CLEAR and /DUMP at the same time

	MOVEI	T1,CHOMOD	;SET OUTPUT MODE
	SKIPN	T2,DEV		;GET DEVICE
	MOVSI	T2,'DSK'	;DEFAULT TO DISK
	MOVSI	T3,OUTHDR	;POINT TO BUFFER HEADER
	OPEN	CHO,T1		;OPEN FILE
	  USEROR	Can't OPEN the output device

	SKIPN	T1,NAME		;GET FILE NAME
	MOVE	T1,['DXMPA ']	;USE DEFAULT
	SKIPN	T2,EXT		;GET EXTENSION
	HRLZI	T2,'LSD'	;DEFAULT
	TRZ	T2,-1		;CLEAR NULL FLAG
	MOVEI	T3,0		;CLEAR PROTECTION, ETC.
	MOVE	T4,DIRECT	;GET DIRECTORY
	ENTER	CHO,T1		;ENTER FILE
	  USEROR	ENTER failed
	OUTBUF	CHO,0		;SET DEFAULT BUFFERS
;ACCUMULATE HEADING DATA

STRTDM:	MOVE	T1,[POINT 7,HEADER]
	MOVEM	T1,HEDPNT	;INIT POINTER FOR HEADER MSG
	PUSHJ	P,HEDTXT
	 ASCIZ /DX-10 #/
	MOVE	T1,A.CHL	;CHL NUMBER
	PUSHJ	P,HEDDIG	; AND PRINT
	PUSHJ	P,HEDTXT
	 ASCIZ / dump by BOOTDX /
	LDB	T1,[POINT 9,.JBVER##,11]
	PUSHJ	P,HEDOCT	;PRINT VERSION  NUMBER
	LDB	T1,[POINT 6,.JBVER##,17]	;GET MINOR VERSION #
	JUMPE	T1,DMHDV1	;JUMP IF NONE
	SUBI	T1,1		;FAKE OUT DIVIDE
	IDIVI	T1,^D26		;GET LAST LETTER
	JUMPE	T1,DMHDV0	;JUMP IF ONLY 1 LETTER
	ADDI	T1,"A"-1	;CONVERT 1ST LETTER
	PUSHJ	P,HEDCHR
DMHDV0:	MOVEI	T1,"A"(T2)
	PUSHJ	P,HEDCHR	;OUTPUT LAST LETTER

DMHDV1:	HRRZ	T1,.JBVER##	;GET EDIT NUMBER
	JUMPE	T1,DMHDV2	;JUMP IF ZERO
	MOVEI	T1,"("
	PUSHJ	P,HEDCHR
	HRRZ	T1,.JBVER##
	PUSHJ	P,HEDOCT
	MOVEI	T1,")"
	PUSHJ	P,HEDCHR	;FINISH "(EDIT NUMBER)"

DMHDV2:	LDB	T1,[POINT 3,.JBVER##,2]	;GET "WHO MADE EDIT"
	JUMPE	T1,DMHDV3	;JUMP IF DIGITAL DID
	MOVEI	T1,"-"
	PUSHJ	P,HEDCHR
	XCT	DMHDV2		;GET "WHO" BACK
	PUSHJ	P,HEDDIG	; AND PRINT

DMHDV3:	MOVEI	T1,11		;HORIZONTAL TAB
	PUSHJ	P,HEDCHR
	MSTIME	T1,		;GET TIME OF DAY (MILLESECONDS)
	IDIVI	T1,^D60000	;GET MINUTES
	IDIVI	T1,^D60		;GET HOURS
	PUSH	P,T2		;SAVE REMAINDER AS MINUTES
	PUSHJ	P,HEDDEC	;PRINT QUOTIENT AS HOURS
	MOVEI	T1,":"
	PUSHJ	P,HEDCHR	;PRINT COLON
	POP	P,T1		;GET MINUTES BACK
	PUSHJ	P,HEDDEC	; AND PRINT
	MOVEI	T1,11
	PUSHJ	P,HEDCHR	;PRINT TAB

	DATE	T1,
	IDIVI	T1,^D31*^D12	;YEAR GOES TO T1
	ADDI	T1,^D64		;ADD IN BASE YEAR
	IDIVI	T2,^D31		;T2 GETS MONTH, T3 GETS DAY
	PUSH	P,T1		;SAVE YEAR
	PUSH	P,[ASCII /-Jan-/
		   ASCII /-Feb-/
		   ASCII /-Mar-/
		   ASCII /-Apr-/
		   ASCII /-May-/
		   ASCII /-Jun-/
		   ASCII /-Jul-/
		   ASCII /-Aug-/
		   ASCII /-Sep-/
		   ASCII /-Oct-/
		   ASCII /-Nov-/
		   ASCII /-Dec-/](T2)
	MOVEI	T1,1(T3)	;GET DAY
	PUSHJ	P,HEDDEC	; AND PRINT
	POP	P,T1		;GET MONTH
	PUSHJ	P,HED7		; AND PRINT
	POP	P,T1
	PUSHJ	P,HEDDEC	;PRINT YEAR
	MOVE	T1,[20,,11]	;GET SYSTEM
	GETTAB	T1,		; SERIAL NUMBER
	  MOVEI	T1,0		;UNKNOWN
	SKIPLE	T1		;SEE IF OK
	CAILE	T1,^D9999
	JRST	DMHDV5		;SYSTEM NUMBER BAD
	PUSH	P,T1		;SAVE NUMBER
	PUSHJ	P,HEDTXT
	 ASCIZ /	System /
	POP	P,T1
	PUSHJ	P,HEDDEC	;PRINT SYSTEM NUMBER

DMHDV5:	MOVSI	T1,(ASCII /  /)
	PUSHJ	P,HED7		;PRINT SPACES

	MOVSI	T4,-5		;SET HEADER COUNT
DMHDV6:	MOVEI	T1,11		;POINT TO TABLE
	HRL	T1,T4		;POINT TO ENTRY
	GETTAB	T1,		;GET SYSTEM HEADER LINE
	 MOVEI	T1,0		;UNKNOWN
	PUSHJ	P,HED7		;PRINT TEXT
	AOBJN	T4,DMHDV6	;LOOP UNTIL DONE

	MOVEI	T1,0
	PUSHJ	P,HEDCHR	;STUFF NULL IN AT END OF HEADER
	PUSHJ	P,LHEAD		;GO LIST HEADER
	PUSHJ	P,RESET8	;GRONK THE '8
	TELLCR	DX10 dumping

	PUSHJ	P,FETCNF	;GET CONFIG INFO
	PUSHJ	P,PNTCNF	;PRINT MICRO-CODE VER # ON TTY
	MOVEI	T1,LCHAR	;SET UP PRINTER FOR LIST OUTPUT
	MOVEM	T1,OCHLOC	;...
	MOVEI	T1,[ASCIZ "Micro-code version: "]
	PUSHJ	P,LSTTX		;DUMP TO LISTING
	MOVE	T1,VERMP
	PUSHJ	P,LOCT
	MOVEI	T1,"("
	PUSHJ	P,LCHAR		;PRINT CHAR
	MOVE	T1,EDTMP
	PUSHJ	P,LOCT
	MOVEI	T1,[ASCIZ ")   ECO: "]
	PUSHJ	P,LSTTX
	LDB	T1,[POINT 7,FEATUR,26]
	PUSHJ	P,LOCT
	MOVEI	T1,[ASCIZ "   SER: "]
	PUSHJ	P,LSTTX
	LDB	T1,[POINT 9,FEATUR,35]
	PUSHJ	P,LOCT
	PUSHJ	P,LCRLF2
	MOVEI	T1,[ASCIZ "IBUS Registers"]
	PUSHJ	P,LSTTX
	PUSHJ	P,LCRLF2

	MOVEI	P1,17		;ALL SIXTEEN
	MOVSI	P2,RSEL		;SET UP DATAO WORD
RSELUP:	HRRZ	T1,P2		;REGISTER
	PUSHJ	P,LOCT
	PUSHJ	P,LSLSH		;PRINT SLASH TAB
	MOVE	T1,P2
	XCT	PDCDTO(W)	;SELECT REG
	XCT	PDCDTI(W)	;READ IT
	PUSHJ	P,L6OCT		;PRINT SIX OCTAL DIGITS
	TRNN	P1,3		;MOD 4 CRLFS
	JRST	[PUSHJ	P,LCRLF2
		 JRST RSLUP1]
	PUSHJ	P,LTAB
	PUSHJ	P,LTAB
RSLUP1:	ADDI	P2,1		;ADVANCE TO NEXT
	SOJGE	P1,RSELUP	;LOOP TILL DONE
;NOW FETCH MEMORY FROM '8

	SKIPGE	P1,A.DUMP	;GET STARTING ADDRESS
	MOVEI	P1,V.DUMP	;DEFAULT
	MOVEM	P1,A.DUMP
	SKIPGE	P4,A.END	;ENDING LOC
	MOVEI	P4,V.END	;DEFAULT
	MOVE	P3,[POINT 12,MEM8]
	PUSHJ	P,EXAM8		;START DUMPING
	  JRST	[IDPB T1,P3	;STORE WORD
		 AOS T1,ADDRES	;ADVANCE TO NEXT LOC
		 CAMG T1,P4	;DONE?
		 AOS (P)
		 POPJ P,]	;RETURN - TO SELF
	
;NOW DUMP TO LISTING

	MOVE	P3,[POINT 12,MEM8]
	MOVE	T1,A.DUMP	;GET START ADDRS
	MOVEM	T1,ADDRES	;SAVE IT
DLUP:	PUSHJ	P,L4OCT		;PRINT ADDRS
	PUSHJ	P,LSLSH		;SLASH AND TAB
	ILDB	P1,P3		;GET CONTENTS
	MOVE	T1,P1		;PRINT OCTAL
	PUSHJ	P,L4OCT
	PUSHJ	P,LTAB		;TAB
	PUSHJ	P,PNTINS	;PRINT INSTR IN SYMBOLIC
	AOS	T1,ADDRES	;ADVANCE TO NEXT
	CAMG	T1,P4		;DONE?
	JRST	DLUP		;NO - LOOP
	CLOSE	CHO,		;YES - CLOSE FILE
	RELEAS	CHO,
	JRST	GOHOME		;DONE
;ROUTINE TO PRINT A SYMBOLIC INSTRUCTION
;C(P1) := INSTR
;PRESERVE P3,P4

PNTINS:	PUSH	P,[0]		;MARK STACK
	JUMPE	P1,[PUSH P,['...']
		    JRST PNTDMP]
	LDB	T1,[POINT 3,P1,26]
	CAIG	T1,5		;LOOK AT OP CODE
	JRST	PNTNRM		;DO NORMAL ROUTINE
	CAIN	T1,6		;IOT?
	JRST	PNTIOT		;YES - SPECIAL
				;OP = 7 DO SPECIAL HACK
	CAIN	P1,7000
	JRST	[PUSH P,['NOP']
		 JRST PNTDMP]
	TRNN	P1,400		;GROUP 1?
	JRST	PNTG1		;YES
	TRNN	P1,1		;GROUP 2?
	JRST	PNTG2		;YES
	TRNE	P1,200		;GROUP 3
	PUSH	P,['CLA']	;SEE IF CLA BIT ON
	CAIN	P1,7621		;CHECK SPECIAL HACKS
	JRST	[MOVEI T2,'CAM'
		 MOVEM T2,0(P)
		 JRST PNTDMP]
	CAIN	P1,7521
	JRST	[PUSH P,['SWP']
		 JRST PNTDMP]	;GO DUMP
	TRNE	P1,20
	PUSH	P,['MQL']
	TRNE	P1,100
	PUSH	P,['MQA']
PNTXXX:	SKIPN	0(P)		;ANYTHING?
	PUSH	P,['***']
	JRST	PNTDMP		;DUMP LIST
;PRINT GROUP 1 OPR INSTRS

PNTG1:	TRNE	P1,200		;CHECK CLA BIT
	PUSH	P,['CLA']
	TRNE	P1,100
	PUSH	P,['CLL']
	TRNE	P1,1
	PUSH	P,['IAC']
	TRNE	P1,40
	PUSH	P,['CMA']
	TRNE	P1,20
	PUSH	P,['CML']
	LSH	P1,-1		;NOW GET ROTATE INFO
	ANDI	P1,7		;ONLY
	JUMPE	P1,PNTXXX	;GO DUMP IF NONE
	PUSH	P,RTAB(P1)	;ELSE GET FROM TABLE
	JRST	PNTXXX		;AND THEN DUMP

;HERE TO DO GROUP 2 OPR

PNTG2:	TRNE	P1,10		;SLIGHTLY STRANGE
	JRST	PNTG2A
	TRNE	P1,100
	PUSH	P,['SMA']
	TRNE	P1,40
	PUSH	P,['SZA']
	TRNE	P1,20
	PUSH	P,['SNL']
	JRST	PNTG2B

PNTG2A:	TRNE	P1,100
	PUSH	P,['SPA']
	TRNE	P1,40
	PUSH	P,['SNA']
	TRNE	P1,20
	PUSH	P,['SZL']
PNTG2B:	TRNE	P1,200
	PUSH	P,['CLA']
	CAIN	P1,7410		;SPECIAL GROUP 2 OPRS
	PUSH	P,['SKP']
	CAIN	P1,7404
	PUSH	P,['OSR']
	CAIN	P1,7402
	PUSH	P,['HLT']
	JRST	PNTXXX
;HERE TO PRINT NORMAL OP-CODES (0-5)

PNTNRM:	PUSH	P,ITAB(T1)
	TRNE	P1,400		;LOOK FOR INDIRECT
	PUSH	P,['I']
	TRNN	P1,200
	PUSH	P,['0']		;NOT PAGE 0 BIT
	MOVE	T1,P1		;MAKE COPY OF INSTR
	ANDI	T1,177		;GET ADDRS PART
	MOVE	T2,ADDRES	;SEE WHAT PAGE WE ARE ON
	ANDI	T2,7600		;PAGE # ONLY
	TRNE	P1,200		;WAS IT PAGE 0?
	ADD	T1,T2		;NO - ADD IN PAGE FIELD
	MOVEI	P1,4		;CONVERT TO 4 DIGIT SIXBIT
	LSHC	T1,-3
	LSH	T2,-3
	SOJG	P1,.-2		;MAKE INTO ZONE DIGITS
	LSH	T2,-^D12	;RIGHT JUSTIFY
	IOR	T2,['0000']	;MAJIK
	PUSH	P,T2		;STACKIT
	JRST	PNTDMP		;GO DUMP THIS MES

;HERE TO PRINT IOT (6) INSTRUCTIONS

PNTIOT:	CAILE	P1,6007		;CHECK FOR BUILTIN
	JRST	PNTIOX		;NO - MUST BE DX10 SPECIFIC
	ANDI	P1,7		;MASK OUT TRASH
	PUSH	P,DTAB(P1)	;STASH OP
	JRST	PNTDMP		;AND DUMP

;HERE FOR DX10 IOTS

PNTIOX:	CAIL	P1,6500		;CHECK RANGE
	CAILE	P1,6577		;FOR VALID IOT
	JRST	PNTXXX		;LOSE
	PUSH	P,XTAB-6500(P1)
	JRST	PNTDMP		;GO DUMP
;HERE TO DUMP STACKED ATOMS

PNTDMP:	MOVE	P1,P		;COPY OF PDP
	SUB	P1,[1,,1]	;LOOK FOR MARKER
	SKIPE	0(P1)		;???
	JRST	.-2		;NO - KEEP LOOKING
	SUB	P1,[1,,1]	;BACK ONE MORE
	PUSH	P,P1		;SAVE THIS
	AOBJN	P1,PNTNXA	;ADVANCE AND START DUMPING

PNTNXT:	MOVE	T2,0(P1)	;FETCH ATOM
	MOVEI	T3,6		;MAX 6 CHARS
PNTNX1:	MOVEI	T1,0		;CLEAR T1
	LSHC	T1,6		;GET CHAR
	JUMPE	T1,PNTNX2	;SKIP NULLS
	ADDI	T1,40		;CONVERT TO ASCII
	PUSHJ	P,LCHAR		;DUMP CHAR
PNTNX2:	SOJG	T3,PNTNX1	;LOOP TILL DONE
	MOVEI	T1," "		;PRINT SPACE
	PUSHJ	P,LCHAR
PNTNXA:	AOBJN	P1,.+1		;ADVANCE TO NEXT
	CAME	P1,P		;DONE
	JRST	PNTNXT
	MOVE	P,0(P)		;MORE OBSCURITY
	JRST	LCRLF		;CRLF AND RETURN
;MAJIK TABLES

RTAB:	'***'
	'BSW'
	'RAL'
	'RTL'
	'RAR'
	'RTR'
	'***'
	'***'

ITAB:	'AND'
	'TAD'
	'ISZ'
	'DCA'
	'JMS'
	'JMP'

DTAB:	'SKON'
	'ION'
	'IOF'
	'SRQ'
	'GTF'
	'RTF'
	'SGT'
	'CAF'

;MOBY TABLE FOR DX10 IOT'S

XTAB:	'CCC'		;6500
	'SLB'
	'STM'
	'G8A'
	'G8B'
	'G8C'
	'GBI'
	'GTI'
	'LCB'
	'L8S'
	'LSF'
	'L8A'
	'L8B'
	'L8C'
	'LIS'
	'LBO'
	'TCP'
	'TBD'
	'TSF'
	'TSR'
	'TCL'
	'TCT'
	'TSA'
	'TRI'
	'***'		;6530
	'CAD'
	'CCM'
	'CSV'
	'COP'
	'CHL'
	'CSE'
	'CSU'
	'T8R'
	'TBP'
	'TDN'
	'TBC'
	'TOR'
	'***'		;6545
	'***'		;6546
	'***'		;6547
	'MRD'
	'MWR'
	'D8S'
	'LIL'
	'LIR'
	'GIL'
	'GIR'
	'I8S'
	'***'		;6560
	'***'		;6561
	'***'		;6562
	'***'		;6563
	'***'		;6564
	'***'		;6565
	'***'		;6566
	'SSA'
	'SVB'
	'SAD'
	'SCM'
	'SVA'
	'SOP'
	'SHL'
	'SSE'
	'SSU'		;6577
SUBTTL	HEADER CONSTRUCTION SUBROUTINES

HEDTXT:	POP	P,T2		;PRINT STRING, CALLED WITH PUSHJ
	HRLI	T2,(POINT 7,,)	;CHANGE PC TO BYTE POINTER
HEDTX2:	ILDB	T1,T2		;GET NEXT BYTE
	JUMPE	T1,1(T2)	;RETURN ON 0 CHARACTER
	PUSHJ	P,HEDCHR	;PRINT CHARACTER
	JRST	HEDTX2		;LOOP FOR MORE

HEDOCT:	TDZA	T3,T3		;PRINT OCTAL NUMBER, CALLED BY PUSHJ
HEDDEC:	MOVEI	T3,2		;PRINT DECIMAL NUM, CALLED BY PUSHJ
	MOVE	T4,T3		;FOR DECIMAL NUMS, FORCE 2 DIGITS
HEDNUM:	IDIVI	T1,10(T3)
	HRLM	T1+1,(P)
	SOSG	T4		;FORCE DIGITS
	SKIPE	T1
	PUSHJ	P,HEDNUM
	HLRZ	T1,(P)
HEDDIG:	ADDI	T1,"0"		;PRINT DIGIT
HEDCHR:	IDPB	T1,HEDPNT	;PRINT CHARACTER
	POPJ	P,

HED7:	MOVEI	T2,5		;PRINT 5 ASCII CHARS, CALLED BY PUSHJ
HED7A:	ROT	T1,7		;GET NEXT CHARACTER
	TRNE	T1,177		;SKIP IF NULL
	PUSHJ	P,HEDCHR
	SOJG	T2,HED7A	;LOOP UNTIL 5 PRINTED
	POPJ	P,
;LIST HEADING

LHEAD:	MOVEI	T1,HEADER	;GET HEADER
	PUSHJ	P,LSTTX		;LIST IT
				;FALL INTO LCRLF2

;LIST END OF LINE AND A BLANK LINE

LCRLF2:	PUSHJ	P,LCRLF
LCRLF:	MOVEI	T1,[BYTE (7)15,12]
				;FALL INTO LSTTX

;LIST ASCIZ STRING

LSTTX:	MOVE	T2,T1		;GET POINTER
	HRLI	T2,(POINT 7,,)	;SET ASCII POINTER
LSTTXL:	ILDB	T1,T2		;GET CHARACTER
	JUMPE	T1,RETRET	;RETURN IF DONE
	PUSHJ	P,LCHAR		;ELSE LIST IT
	JRST	LSTTXL		;LOOP UNTIL DONE

;LIST SLASH - FALL INTO LTAB

LSLSH:	MOVEI	T1,"/"
	PUSHJ	P,LCHAR

;LIST TAB

LTAB:	MOVEI	T1,11		;GET TAB
				;FALL INTO LCHAR

;LIST CHARACTER

LCHAR:	SOSG	OUTHDR+2	;COUNT CHARACTER IN BUFFER
	JRST	LCHARB		;NO ROOM--GO MAKE SOME
LCHARL:	IDPB	T1,OUTHDR+1	;OK--STORE CHARACTER
RETRET:	RETURN

LCHARB:	OUT	CHO,		;OUTPUT DATA BUFFER
	  JRST	LCHARL		;AND NOW GO DO CHARACTER
	ERROR	Output device error
	SUBTTL	COMMAND SCANNER

GETCOM:	OUTSTR	[ASCIZ /File: /]	;TELL USER WE ARE WAITING
COMLP:	PUSHJ	P,GETNAM	;GET A SIXBIT NAME
	JRST	.+2
COMFND:	MOVEI	T2,0		;CLEAR NAME
	MOVSI	T4,-BRKLEN	;LOOK FOR BREAK
	HLRZ	T3,BRKTAB(T4)	;TRY NEXT BREAK
	CAME	T1,T3		;SEE IF MATCH
	AOBJN	T4,.-2		;LOOP UNTIL MATCH
	HRRZ	T3,BRKTAB(T4)	;GET DISPATCH ADDRESS
	JRST	(T3)		;JUMP TO HANDLE BREAK

BRKTAB:	" ",,COMNOP		;SPACE IS A NO-OP
	".",,COMEXT		;DOT IS EXTENSION
	":",,COMDEV		;COLON IS DEVICE
	"[",,COMDIR		;BRAKET IS DIRECTORY
	"/",,COMSWT		;SLASH IS SWITCH
	12,,CMDEND		;RETURN AT END OF LINE, AFTER SAVING FILE NAME
	32,,GOHOME		;IF ^Z
	3,,GOHOME		;IF ^C
BRKLEN==.-BRKTAB
	0,,COMERR		;ELSE, MUST BE ERROR

COMERR:	USEROR	Command error--type /H for help
COMNOP:	PUSHJ	P,SAVNAM	;STORE FILE NAME
	JRST	COMLP		;AND GO AROUND AGAIN

COMEXT:	PUSHJ	P,SAVNAM	;SAVE FILE NAME
	PUSHJ	P,GETNAM	;GET SIXBIT NAME
	HLLOM	T2,EXT		;SAVE EXT WITH FLAG FOR DOT
	JRST	COMFND		;AND GO AROUND AGAIN

COMDEV:	MOVEM	T2,DEV		;SAVE DEVICE
	JRST	COMLP		;GO AROUND AGAIN

COMDIR:	PUSHJ	P,SAVNAM	;SAVE FILE NAME
	PUSHJ	P,GETOCT	;GET OCTAL NOW
	CAIN	T1,"-"		;SEE IF DEFAULT
	JUMPE	T2,[PUSHJ P,GETCHR
		    JRST  COMDIX]
	HRLZ	T2,T2		;POSITION IT
	SKIPN	T2		;SKIP IF SOMETHING THERE
	GETPPN	T2,		;NO--GET FROM SYSTEM
	  JFCL
	HLLZM	T2,DIRECT	;SAVE FOR LATER
	CAIE	T1,","		;VERIFY COMMA
	JRST	COMERR		;NO--GIVE UP IN DISGUST
	PUSHJ	P,GETOCT	;GET PROGRAMMER
	SKIPN	T2		;SKIP IF SOMETHING THERE
	GETPPN	T2,		;ELSE ASK MONITOR
	  JFCL
	HRRM	T2,DIRECT	;STORE FOR LOOKUP
	CAIE	T1,","		;SEE IF SFD COMING
	JRST	COMDIX		;NO--GO FINISH UP
	MOVEI	T2,DIRPTH	;YES--SHIFT TO SFD
	EXCH	T2,DIRECT	; FORMAT
	MOVEM	T2,DIRPTH+2	; ..
	MOVSI	T4,-5		;MAX SFD COUNT
COMDIL:	PUSHJ	P,GETNAM	;GET SFD NAME
	JUMPE	T2,COMERR	;ERROR IF BLANK
	MOVEM	T2,DIRPTH+3(T4)	;STORE
	CAIN	T1,","		;SEE IF MORE
	AOBJN	T4,COMDIL	;YES--GO GET UNLESS TOO MANY
COMDIX:	CAIN	T1,"]"
	JRST	COMLP
	CAIN	T1,12
	JRST	COMFND
	JRST	COMERR
;HERE ON END OF COMMAND TO CHECK AND DEFAULT DX10/DX20 TYPE VALUES

CMDEND:	SKIPL	A.DX10		;SPECIFY BOTH /DX20 AND
	SKIPGE	A.DX20		;  /DX20?
	CAIA			;NO, CONTINUE
	USEROR	<Can't specify both /DX10 and /DX20>
	SETOB	RHNUM,DRVNUM	;ASSUME DX10
	SKIPL	A.DX10		;WERE WE CORRECT?
	JRST	SAVNAM		;YES, LEAVE RHNUM .LT. 0
	SKIPGE	RHNUM,A.DX20	;/DX20 SPECIFIED?
	SKIPL	[V.DFLT]	;NO, IS DEFAULT DX20?
	CAIA			;YES, CONTINUE WITH RHNUM .GE. 0
	JRST	SAVNAM		;NO, LEAVE RHNUM .LT. 0
	SKIPGE	T1,A.DX20	;VALUE SPECIFIED ON /DX20 SWITCH?
	MOVEI	T1,V.DX2T	;NO, USE DEFAULT
	MOVEM	T1,A.DX20	;AND STORE BACK
	SKIPGE	A.CHL		;/UNIT SPECIFIED?
	JRST	SAVNAM		;NO, LEAVE RHNUM .GE.0, DRVNUM .LT. 0
	MOVE	RHNUM,A.CHL	;GET VALUE OF /UNIT SWITCH
	IDIVI	RHNUM,10	;COMPUTE CORRECT RHNUM AND DRVNUM
SAVNAM:	SKIPE	T2		;IF NAME,
	MOVEM	T2,NAME		; SAVE FOR LOOKUP
	POPJ	P,		;RETURN
;HERE WHEN SWITCH TO BE PROCESSED

COMSWT:	PUSHJ	P,SAVNAM	;SAVE FILE NAME
	PUSHJ	P,GETNAM	;GET SIXBIT WORD
	PUSH	P,T1		;SAVE BREAK CHARACTER
	MOVE	T1,[-SWTLEN,,SWTTAB] ;AOBJN POINTER TO NAMES
	PUSHJ	P,FNDNAM	;FIND NAME IN TABLE
	HRRZ	P1,T1		;SAVE OFFSET OF MATCH
	HLRZ	T2,SWTVAL(P1)	;GET DEFAULT VALUE
	MOVE	T1,0(P)		;GET BACK BREAK CHARACTER
	CAIE	T1,":"		;SEE IF VALUE TYPED IN
	JRST	SWTWN2		;NO, USE DEFAULT
	CAIN	P1,DX20DX	;PROCESSING /DX20 SWITCH?
	JRST	SWTWN1		;YES, THAT'S DIFFERENT
	PUSHJ	P,GETOCT	;GET OCTAL VALUE OF SWITCH
	MOVEM	T1,0(P)		;SAVE BREAK CHARACTER
	JRST	SWTWN2		;AND CONTINUE
SWTWN1:	PUSHJ	P,GETNAM	;GET SIXBIT VALUE OF SWITCH
	MOVEM	T1,0(P)		;SAVE BREAK CHARACTER
	MOVE	T1,[-DX2TBL,,DX2TAB] ;AOBJN POINTER FOR LEGAL VALUES
	PUSHJ	P,FNDNAM	;LOOK FOR IT
	HRRZ	T2,T1		;MOVE TO PROPER PLACE
SWTWN2:	HRRZ	T3,SWTVAL(P1)	;GET ADDRESS OF SWITCH
	JUMPE	T3,HELP		;NONE--MUST BE /H
	MOVEM	T2,(T3)		;STORE ANSWER
	CAIG	P1,DEFIDX	;DID USER TYPE A SWITCH AFFECTING LOAD/START?
	SETOM	NODEF		;YES, DON'T DO AUTO START
	POP	P,T1		;RESTORE BREAK CHARACTER
	JRST	COMFND		;GO HANDLE BREAK
NODEF:	Z		;=0 IF USER SPECIFIES NO SWITCHES
SWTTAB:	SIXBIT	/CLEAR/
	SIXBIT	/DUMP/
	SIXBIT	/END/
	SIXBIT	/HELP/
	SIXBIT	/LOAD/
	SIXBIT	/START/
DEFIDX==.-SWTTAB-1
	SIXBIT	/UNIT/
UNIDX==.-SWTTAB-1
	SIXBIT	/TYPE/
	SIXBIT	/CPU/
	SIXBIT	/DX10/
	SIXBIT	/DX20/
DX20DX==.-SWTTAB-1
SWTLEN==.-SWTTAB
SWTVAL:	V.CLR,,A.CLR		;DEFAULT,,LOCATION
	V.DUMP,,A.DUMP
	V.END,,A.END
	0
	0,,A.LOAD
	V.STRT,,A.STRT
	0,,A.CHL
	V.TYPE,,A.TYPE
	0,,A.CPU
	0,,A.DX10
	V.DX2T,,A.DX20

DX2TAB:	SIXBIT/TX02/
	SIXBIT/RP20/
DX2TBL==.-DX2TAB


;HERE IF /HELP
HELP:	CAIN	T1,12		;SEE IF AT END OF LINE YET
	JRST	HELP1		;YES--GO DO THE HELP
	PUSHJ	P,GETCHR	;NO--GET ANOTHER CHAR
	JRST	HELP		;AND LOOP
HELP1:	MOVE	1,['BOOTDX']
	PUSHJ	P,.HELPR##
	JRST	START
FNDNAM:	PUSH	P,P1		;SAVE P1
	PUSH	P,T1		;SAVE INITIAL VALUE OF AOBJN POINTER
	MOVSI	P1,770000	;GET INITIAL MASK
FNDNA1:	MOVE	T3,T2		;COPY SIXBIT NAME TO MATCH
	TDZ	T3,P1		;MASK WITH CURRENT MASK
	JUMPE	T3,FNDNA2	;GO IF NO MORE BITS
	ASH	P1,-6		;EXTEND MASK ANOTHER 6 BITS
	JRST	FNDNA1		;AND LOOP
FNDNA2:	SETZM	T4		;CLEAR FOUND COUNTER
FNDNA3:	CAMN	T2,(T1)		;EXACT MATCH?
	JRST	FNDNA5		;YES
	MOVE	T3,(T1)		;GET CURRENT ENTRY
	AND	T3,P1		;MASK IT
	CAME	T2,T3		;MATCH NOW?
	JRST	FNDNA4		;NO
	SKIPE	T4		;ALREADY FOUND ANOTHER MATCH?
	USEROR	<Ambiguous switch or value -- Type /H for help>
	MOVE	T4,T1		;KEEP POINTER TO MATCH
FNDNA4:	AOBJN	T1,FNDNA3	;LOOP FOR NEXT VALUE
	SKIPN	T1,T4		;ANY MATCHES?
	USEROR	<Unknown switch or value -- Type /H for help>
FNDNA5:	SUB	T1,0(P)		;COMPUTE OFFSET OF MATCH IN TABLE
	POP	P,(P)		;FLUSH STACK
	POP	P,P1		;RESTORE P1
	POPJ	P,		;RETURN
GETNAM:	MOVE	T3,[POINT 6,T2]
	MOVEI	T2,0		;CLEAR NAME
GETNM1:	PUSHJ	P,GETCHR	;GET NEXT CHAR
	CAIL	T1,"A"+40	;SEE IF LC
	CAILE	T1,"Z"+40
	JRST	.+2
	SUBI	T1,40		;YES--MAKE UC
	CAIL	T1,"0"		;SEE IF BREAK
	CAILE	T1,"Z"		; ..
	RETURN
	CAILE	T1,"9"		;OR OK
	CAIL	T1,"A"
	JRST	.+2
	RETURN
	SUBI	T1,40		;CONVERT TO SIXBIT
	TLNE	T3,770000	;SEE IF OVERFLOW
	IDPB	T1,T3		;STORE RESULT
	JRST	GETNM1		;LOOP FOR MORE

GETOCT:	MOVEI	T2,0		;CLEAR RESULT
GETOC1:	PUSHJ	P,GETCHR	;GET NEXT ODGIT
	CAIL	T1,"0"		;SEE IF
	CAILE	T1,"7"		; BREAK
	RETURN
	LSH	T2,3		;MULT BY 8
	ADDI	T2,-"0"(T1)	;INCLUDE ODGIT
	JRST	GETOC1		;LOOP

GETCHR:	INCHWL	T1		;GET NEXT CHARACTER
	JUMPE	T1,GETCHR	;LOOP IF NULL
	CAIE	T1,177		;IF RUB
	CAIN	T1,15		;OR CR
	JRST	GETCHR		;LOOP
	CAIL	T1,175		;IF ALTERNATE ALT MODE
	MOVEI	T1,33		; STANDARDIZE
	CAIN	T1,33		;IF ESCAPE
	MOVEI	T1,12		; MAKE INTO EOL
	CAIE	T1,13		;IF VTAB
	CAIN	T1,14		; OR FORM
	MOVEI	T1,12		; MAKE INTO LF
	CAIN	T1,11		;SEE IF TAB
	MOVEI	T1," "		;YES, CHANGE TO SPACE
	RETURN
SUBTTL	UTILITY SUBROUTINES

;ROUTINE TO GET NEXT BYTE FROM FILE
;RETURNS BYTE IN P1 / PARTIAL CKSUM IN P2

GETBYT:	PUSHJ	P,GETC		;GET FILE CHAR
	ADD	P2,P1		;ADD INTO CKSYM
	POPJ	P,		;RETURN

GETC:	SOSG	INHDR+2
	PUSHJ	P,GETBYI	;RE-FILL BUFFER
	ILDB	P1,INHDR+1	;GET BYTE
	POPJ	P,		;RETURN

;ROUTINE TO GET NEXT WORD FROM FILE
;RETURNS 20000 IF LEADER/TRAILER , 1XXXX IF ADDRESS
;YYYY IF JUST DATA WORD

GETWRD:	MOVEI	P2,0		;PARTIAL CKSUM TO ZERO
	PUSHJ	P,GETBYT	;GET A BYTE
	LSH	P1,6		;PUT IN CORRECT PLACE
	TRNE	P1,20000	;CHECK FOR LEADER/TRAILER
	JRST	GETCH8		;CHECK CHL 8
	PUSH	P,P1		;SAVE FIRST CHAR
	PUSHJ	P,GETBYT	;GET 2ND BYTE
	TRNE	P1,300		;BETTER HAVE 7/8 ZERO
	ERROR	Illegal 2nd character
	IOR	P1,0(P)		;COMBINE
TPOPJ:	POP	P,T1		;PRUNE PDL
CPOPJ:	POPJ	P,		;EXIT

;HERE TO CHECK RANDOMNESS

GETCH8:	TRNE	P1,7700		;GOT ANYTHING
	ERROR	<Trash in file>
	TRNN	P1,10000	;IGNORE FIELD SET ZERO
	POPJ	P,
	JRST	GETWRD		;...

;FILL BUFFER AND CHECK ERRORS

GETBYI:	IN	CHI,0		;DO INPUT
	  POPJ	P,		;OK RETURN
	STATZ	CHI,740000	;HARD ERROR?
	 ERROR	<Input file read error>
	STATZ	CHI,20000	;EOF?
	 ERROR	<Unexpected EOF>
	POPJ	P,		;SYSTEM CONFUSED
;ROUTINE TO CHECK WHAT TYPE OF FILE WE ARE READING

CHKLFT:	PUSHJ	P,GETC		;GET FIRST CHAR OF FILE
	JUMPE	P1,CHKB		;SEE IF BINARY IF NULL
	CAIE	P1,"8"		;SEE IF AN ASCII '8'
	JRST	[PUSHJ P,SKPCOM	;SKIP COMMENT
		 JRST CHKLFT]	;TRY AGAIN
	SETOM	A8FLG		;SAY A8 FILE
	AOS	INHDR+2		;BACKUP INPUT FILE
	MOVSI	T1,70000	;BACK UP BYTE PNTR
	ADDM	T1,INHDR+1	;...
	POPJ	P,		;RETURN

CHKB:	SETSTS	CHI,CHIMOD	;CHANGE TO BINARY MODE
	MOVSI	T1,(POINT 36,0)
	HLLM	T1,INHDR+1
	AOS	T1,INHDR+2	;ADJUST COUNT CORRECTLY
	IDIVI	T1,5
	SKIPE	T2
	ADDI	T1,1		;ROUND UP
	MOVEM	T1,INHDR+2
	SETZM	A8FLG		;SAY BIN FILE
	POPJ	P,

;ROUTINE TO SKIP COMMENTS

SKPCOM:	CAIE	P1,";"		;VALID COMMENT CHAR?
	ERROR	<File not in A8 format>
SKPCM1:	PUSHJ	P,GETC		;GET CHAR TILL  EOL
	CAIE	P1,12		;LINE FEED?
	JRST	SKPCM1		;NO - LOOP
	POPJ	P,		;YES - RETURN

;ROUTINE TO DO THE SETUUO THAT WILL FORCE US TO RUN ONLY ON THE
;CPU SPECIFIED IN THE /CPU SWITCH.  IF NO SWITCH IS SPECIFIED,
;CPU 0 IS ASSUMED.

SETCPU:	SKIPGE	T2,A.CPU	;CPU SPECIFIED?
	MOVEI	T2,0		;NO, ASSUME ZERO
	MOVEI	T1,SP.CR0	;GET CPU0 BIT
	LSH	T1,(T2)		;SHIFT TO POSITION FOR THIS CPU
	HRLI	T1,.STCPU	;SETUP SETUUO FUNCTION CODE
	SETUUO	T1,		;PUT US ON THAT CPU
	  WARNCR <Unable to restrict execution to specified CPU>
	POPJ	P,		;RETURN
;PDP-8 A8 UTILITIES

GET2W:	PUSH	P,[0]		;INIT ANSWER
	PUSHJ	P,GETA8		;GET FIRST CHAR
	 JRST	GET2X		;EXIT IF NOT DIGIT
	MOVEM	P1,0(P)		;STASH ON PDL
	PUSHJ	P,GETA8		;GET NEXT
	 JRST	GET2X		;MUST BE SINGLE DIGIT
	EXCH	P1,0(P)		;NEW LOW ORDER BYTE
	LSH	P1,6		;MAKE HIGH ORDER BYTE
	IORM	P1,0(P)		;COMBINE
	PUSHJ	P,GETC		;GET NEXT FILE CHAR
GET2X:	MOVE	P2,P1		;RETURN BREAK CHAR IN P2
	POP	P,P1		;RESTORE WORD TO P1
	POPJ	P,		;EXIT

;GET NEXT FILE CHAR AND RETURN LOW 6 BITS

GETA8:	PUSHJ	P,GETC		;GET CHAR FROM FILE
	CAIE	P1,","		;CHECK TERMINATOR
	CAIN	P1,15
	POPJ	P,		;NON SKIP RETURN
	ANDI	P1,77		;TRIM TO LOW ORDER 6-BIT
	JRST	CPOPJ1		;SKIP IF CHAR OK

;GET WORD COUNT FFROM FILE

WCREAD:	PUSHJ	P,GETC		;GET CHARACTER
	CAIE	P1,"8"		;CHECK VALIDITY
	JRST	[PUSHJ P,SKPCOM	;SKIP COMMENT
		 JRST WCREAD]
	PUSHJ	P,GETC		;GET NEXT CHARACERR
	CAIE	P1," "		;BETTER BE A SPACE
	ERROR	<File not in correct A8 format>
	SETZM	CHKSUM		;INIT CHECKSUM
				;NOW GET DATA WORD
WDREAD:	PUSHJ	P,GET2W		;GET 12 BIT NUMBER
	ADDM	P1,CHKSUM	;ADD TO CHECKSUM
	CAIE	P2,","		;GRNTEE COMMA TERMINATOR
	ERROR	<File not in correct A8 format>
	POPJ	P,		;RETURN (ANSWER IN P1)
;PRINT OCTAL 4 DIGIT NUMBERS

L6OCT:	SKIPA	T3,[6]		;GRNTEE 6 DIGITS
L4OCT:	MOVEI	T3,4		;GRNTEE 4 DIGITS
PNTO1:	IDIVI	T1,10
	HRLM	T2,0(P)
	SOSLE	T3
	PUSHJ	P,PNTO1		;RECURSE
PNTO2:	HLRZ	T1,0(P)		;GET DIGIT
	ADDI	T1,"0"
	JRST	@OCHLOC

TTOCH:	OUTCHR	T1		;PRINT IT
	POPJ	P,		;RETURN

;CLEANUP ROUTINE

EXITX:	JSP	T1,.+1		;GET PC
	TLNN	T1,(1B6)	;CHECK USER IOT
	JRST	EXITXA		;JUST LEAVE
	PUSHJ	P,HALT8		;STOP '8 IF IN USER IOT

;HERE TO EXIT

GOHOME:	PUSHJ	P,RESTOR	;RESTORE STATUS/CLR ERRORS
EXITXA:	RESET			;TURN OFF USER IOT
	HLLZM	.JBINT##	;DISABLE ^C INTERCEPT
	EXIT	1,		;.
	JRST	.-1

;ROUTINE TO RESTORE STATUS REG

RESTOR:	JUMPGE	RHNUM,CPOPJ
	MOVEI	T1,1		;ANOTHER SNOOZE
	SLEEP	T1,
	  JFCL
	MOVEI	T1,CLRERR	;CLEAR ERRORS
	XCT	PDCCNO(W)	;...
	MOVE	T1,PISAVE	;PUT REG BACK
	XCT	T1,PDCCNO(W)
	POPJ	P,		;RETURN

;PRINT CONFIG INFO

PNTCNF:	OUTSTR	[ASCIZ /" Micro-code version: /]
	MOVE	T1,VERMP
	PUSHJ	P,LOCT		;PRINT OCTAL
	OUTCHR	["("]
	MOVE	T1,EDTMP
	PUSHJ	P,LOCT
	OUTSTR	[BYTE (7)")",15,12]
	POPJ	P,
;ROUTINE TO TYPE OUT OCTAL NUMBERS AS THEY ARE

LOCT:	IDIVI	T1,10		;GET FIRST DIGIT EVEN IF ZERO
	HRLM	T2,0(P)		;STORE ON PDL
	SKIPE	T1		;QUITE WHEN ZERO
	PUSHJ	P,LOCT
	JRST	PNTO2		;TYPE IT
SUBTTL SPECIAL PDP-8 ROUTINES

;ROUTINE TO RESET DX10 AND STOP THE '8
RESET8:	PUSHJ	P,SETCPU	;SET CPU ONLY ON CPU SPECIFIED
	MOVEI	T1,CCINT	;SET UP ^C INTERCEPT
	HRRM	T1,.JBINT##	;SAVE IN CORRECT PLACE
	SETZB	T1,CCINTP	;ZAP
	TRPSET	T1,		;GET GOOD PRIVS
	 ERROR <TRPSET failed>
	JUMPGE	RHNUM,RESET2
	XCT	PDCCNI(W)	;GET STATUS REG
;**;[23] after RESET8 plus 7 lines insert code
	SKIPN	T1		;[23] skip if DX10 exists
	USEROR	No DX10 channel on specified CPU
				;[23] give him an error and restart
	ANDI	T1,PIMASK	;MASK WHAT WE WANT TO SAVE
	MOVEM	T1,PISAVE	;SAVE IT
	SKIPGE	A.DUMP		;SKIP RESET IF DUMPING
	SKIPL	A.END
	JRST	NORST
	MOVE	T1,[DXCLR]	;CLEAR OUT DX10
	XCT	PDCDTO(W)	;...

NORST:	XCT	PDCCNI(W)	;GET RUN INDICATOR
	TLNE	T1,RUNIND	;IS '8 RUNNING
	PUSHJ	P,HALT8		;YES - STOP IT
	MOVEI	T1,1		;SLEEP A SEC HERE TOO
	SLEEP	T1,
	  JFCL
	MOVEI	T1,CLRERR
	XCT	PDCCNO(W)	;ZAP REG ONCE MORE
	MOVE	T1,[RSEL,,MPCTL]
	XCT	PDCDTO(W)	;SELECT SW REG
	XCT	PDCDTI(W)	;READ IT
	ANDI	T1,MPSS!MPHALT!MPCONT
	TRZE	T1,MPCONT	;CLEAR CONT & SKIP IF OFF
	XCT	PDCDTO(W)	;TURN IT OFF IF ON
	MOVEM	T1,SW8		;SAVE REG
	POPJ	P,		;RETURN
;ROUTINE TO TRY TO STOP PDP-8

HALT8:	JUMPGE	RHNUM,CPOPJ
	MOVE	T1,[RSEL,,MPCTL]
	XCT	PDCDTO(W)	;SELECT CORRECT REG
	XCT	PDCDTI(W)	;READ IT
	TRO	T1,MPHALT	;SET HALT FLAG
	XCT	PDCDTO(W)	;HALT '8
	MOVEI	T2,2		;TRY TWICE
HALT8A:	MOVEI	T1,1		;SLEEP FOR A SEC
	SLEEP	T1,		;ZZZZZ
	  JFCL
	XCT	PDCCNI(W)	;READ STATUS
	TLNE	T1,RUNIND	;RUNNING?
	SOJG	T2,HALT8A	;YES - TRY ONCE MORE
	JUMPG	T2,CPOPJ	;OK IF OFF
	ERROR	<Cannot halt DX10>
;ROUTINE TO CLEAR OUT PDP-8 MEMORY

CLEAR:	JUMPGE	RHNUM,CLRDX
	TELLCR	Clearing DX10
	MOVEI	P1,0		;START OF AREA TO CLEAR
	MOVE	T1,A.CLR	;CHECK VALIDITY OF ADDRESS
	CAIL	T1,V.CLR	;CHECK UPPER BOUND
	MOVEI	T1,V.CLR	;DEFAULT
	MOVEM	T1,A.CLR	;SAVE VALUE
	MOVE	T1,[RSEL,,MPADR]
	XCT	PDCDTO(W)	;SELECT ADDR
	MOVE	T1,P1		;SET ADDESS
	XCT	PDCDTO(W)	;...

CLEARL:	MOVE	T1,[RSEL,,MPCTL]
	XCT	PDCDTO(W)	;SELECT CTL REG
	MOVEI	T1,ENDEP!HLTINS	;ZAP MEMORY WITH HALTS
	IOR	T1,SW8		;OLD SW REG
	XCT	PDCDTO(W)	;WRITE IT
	AOS	T1,P1		;ADVANCE TO NEXT
	CAMLE	T1,A.CLR	;DONE?
	POPJ	P,		;YES - RETURN
	PUSHJ	P,CKCPMA	;CHECK MEM ADV
	JRST	CLEARL		;LOOP TILL DONE

;ROUTINE TO CHECK IF AUTO MA ADVANCE HAPPENED
;C(T1) HAS CORRECT VALUE

CKCPMA:	PUSH	P,T1		;SAVE T1
	MOVE	T1,[RSEL,,MPADR]
	XCT	PDCDTO(W)	;SELECT ADR
	XCT	PDCDTI(W)	;READ WHAT IT THINKS
	ANDI	T1,7777		;MASK
	CAMN	T1,0(P)		;AGREE?
	JRST	CKCPMX		;YES - EXIT
	SETOM	VERERR		;FLAG ERROR
	OUTSTR	[ASCIZ /? CPMA incr error. CPMA = /]
	PUSHJ	P,L4OCT		;PRINT ERROR INFO
	OUTSTR	[ASCIZ /  should be = /]
	MOVE	T1,0(P)		;GET CORRECT VALUE
	PUSHJ	P,L4OCT		;PRINT IT
	OUTSTR	[BYTE (7)15,12]	;CRLF
	MOVE	T1,0(P)		;NOW SET CORRECT VALUE
	XCT	PDCDTO(W)	;...
CKCPMX:	MOVE	T1,[RSEL,,MPCTL]
	XCT	PDCDTO(W)	;RESELECT CTL REG
	JRST	TPOPJ		;PRUNE & EXIT
;ROUTINE TO START '8 AT C(P2)

START8:	CAILE	P2,7777		;CHECK VALIDITY
	ERROR	<Invalid starting address>
	MOVE	T1,[RSEL,,MPCTL]
	XCT	PDCDTO(W)	;SELECT CTRL REG
	MOVEI	T1,MPHALT	;GRNTEE HALT UP
	XCT	PDCDTO(W)	;...
	MOVE	T1,[RSEL,,MPADR]
	XCT	PDCDTO(W)	;SELECT ADDRS
	MOVE	T1,P2		;GET START LOC
	XCT	PDCDTO(W)	;STUFF IT
	MOVE	T1,[RSEL,,MPCTL]
	XCT	PDCDTO(W)
	MOVEI	T1,MPCONT	;SET CONTINUE
	XCT	PDCDTO(W)	;START WORLD
	MOVEI	T1,MPERR	;CLEAR 8A ERROR
	XCT	PDCCNO(W)
	MOVEI	T2,2		;TRY TWICE
STARTL:	MOVEI	T1,1		;SLEEP FOR 1 SEC
	SLEEP	T1,		;ZZZZ
	  JFCL
	XCT	PDCCNI(W)	;READ REGS
	TRNN	T1,MPERR	;CHECK EVERYTHING OK
	TLNN	T1,RUNIND	;RUNNING?
	SOJG	T2,STARTL	;NO - TRY AGAIN
	JUMPG	T2,CPOPJ	;EXIT IF OK
	ERROR	<Cannot start DX10>
	SUBTTL	DX20 LOAD AND START ROUTINES
;TESDSW - CHECK THE SPECIFIED DX20 BY /D SWITCH
; 
;	CALL TESDSW
;
; RETURN+1:ALWAYS W/H NO ERROR
; GOTO ERR17/ERR18 WHEN NO SPECIFIED RH20 OR DRIVE

TESDSW:	MOVE	T3,RHNUM	;GET RH20 NUMBER
	PUSHJ	P,CHKRH2	;SPECIFIED RH20 THERE?
	  ERROR	<Specified RH20 does not exist>
	MOVE	T4,DRVNUM	;GET DRIVE NUMBER
	PUSHJ	P,CHKDRV	;SPECIFIED DRIVE DX20?
	  ERROR	<Specified device is not a DX20>
	PUSHJ	P,PRHDRV	;PRINT OUT DX20 SELECTED
	POPJ	P,		;GOOD RETURN


;RESET2 - RESET THE DX20
RESET2:	MOVEI	T3,DXMTR	;GET THE REGISTER
	MOVE	T4,DRVNUM	;GET THE DRIVE NUMBER
	MOVEI	T2,DX.RST	;SET THE RESET BIT
	PUSHJ	P,WTREG		;RESET DX20
	POPJ	P,
;CHKRH2 - CHECKS IF THE SPECIFIED RH20 IN EXISTENCE, IF SO, SETS IT UP.
; T3/RH20 NUMBER
;
;	CALL CHKRH2
;
; RETURN+1: FAIL, SPECIFIED RH20 NOT EXISTS.
; RETURN+2: FOUND SPECIFIED RH20, AND SET IT UP FOR OPERATION
; DESTROYS T3

CHKRH2:	LSH	T3,2		;MULTIPLY RH20 NUMBER BY 4
				; ***TEMPORARY WAY TO GET DEVICE CODE
	ADDI	T3,540		;540= DEVICE CODE FOR RH20
	LSH	T3,^D24		;FLUSH LEFT
	PUSHJ	P,DEVXCT	;GET STATUS BACK
	 CONI 0,T1		; IN T1
	JUMPLE	T1,CPOPJ	;NOT THERE IF CONI YIELDS ALL ZEROS.
				; SIGN BIT MEANS KLIPA OR KLINI,
				; NOT REALLY AN RH20.
	TRNE	T1,400		;MASSBUS ENABLED?
	JRST	CHKRH3		;YES
	PUSHJ	P,DEVXCT	;NO, DO SO NOW
	 CONO	0,400
CHKRH3:	MOVE	T1,[CONO 0,CO.MEN(T2)]	;SET UP IOT'S????
	IOR	T1,T3		;SET DEVICE CODE	
	MOVEM	T1,RH2CNO	;STORE IT
	MOVE	T1,[CONI 0,T1]	;CONI STATUS
	IOR	T1,T3		;SET DEVICE CODE

	MOVEM	T1,RH2CNI	;STORE IT
	MOVE	T1,[DATAO 0,T2]	;DATAO INSTR.
	IOR	T1,T3		;SET DEVICE CODE
	MOVEM	T1,RH2DTO	;STORE IT
	MOVE	T1,[DATAI 0,T1]	;DATAI INTR.
	IOR	T1,T3		;SET DEVICE CODE
	MOVEM	T1,RH2DTI	;STORE IT
	JRST	CPOPJ1		;SKIP RETURN

SUBTTL ROUTINES FOR COMMAND PROCESSING MODULE
;LOKDX - LOOK FOR THE ONLY ONE DX20 ON THE SYSTEM
;
;	CALL LOKDX
;
; RETURN+1: SUCCESS RETURN, RETURN RHNUM & DRVNUM FOR THE DX20
; USES Q1 & Q2, CONSIDER ERROR IF 0 OR MORE THAN 1 DX20'S FOUND

LOKDX:	MOVSI	Q1,-10		;SETUP COUNTER, AT MOST 10 RH20'S
LOKDX1:	HRRZ	T3,Q1		;GET RHNUM
	PUSHJ	P,CHKRH2	;CHECK FOR EXISTENCE
	  JRST LOKDX4		;JUMP, NOT EXISTS
	HRRZM	Q1,RHNUM	;YES, SAVE RHNUM FOR THIS RH20
	MOVSI	Q2,-10		;SETUP COUNTER, AT MOST 10 DRIVES
LOKDX2:	HRRZ	T4,Q2		;GET DRIVE NUMBER
	PUSHJ	P,CHKDRV	;CHECK DRIVE IF DX20?
	  JRST LOKDX3		;JUMP,NOT THIS DRIVE
	TROE	F,DXFND		;WAS DX20 FOUND?
	ERROR	<More than 1 DX20 found - use /UNIT switch>
	HRRZM	Q2,DRVNUM	;ONLY ONE FOUND, SAVE DRVNUM
	HRRZM	Q1,XRHNUM	;SAVE THE RHNUM FOR THE RH20
	MOVE	T4,[XWD RH2CNI,XRHCNI]	;SET UP T4
	BLT	T4,XRHDTO	;SAVE IO INTR.'S FOR THIS RH20
LOKDX3:	AOBJN	Q2,LOKDX2	;GO BACK, TRY NXT DRIVE
LOKDX4:	AOBJN	Q1,LOKDX1	;GO BACK, TRY NXT RH20
	TRZN	F,DXFND		;FOUND THE DX20?
	ERROR	<No DX20 found>
	MOVE	RHNUM,XRHNUM	;YES,RESTORE THE RH20 NUMBER
	MOVE	T4,[XWD XRHCNI,RH2CNI]	;SETUP T4
	BLT	T4,RH2DTO	;RESTORE IO INSTR. FOR THE RH20
	POPJ	P,		;YES, RETURN
;CLRDX - CLEARS THE MEMORY OF DX20
;
;	CALL CLRDX
; USES Q1

CLRDX:	MOVEI	Q1,3777		;2K LOC.'S IN CRAM
CLRDX1:	MOVE	T2,Q1		;GET ADDR. IN T2
	PUSHJ	P,PRECR		;SET IT UP
	PREWT	(DXDR0)		;SELCT IR REGISTER
	PUSHJ	P,WTRGX		;WRITE INTO CRAM
	SOJG	Q1,CLRDX1	;BACK DO IT AGAIN

;NOW LOAD WORKING MEMORY

	MOVEI	Q1,1777		;1K LOC.S IN WM
	MOVEI	T2,0		;START AT LOC. 0
	PUSHJ	P,PREWM		;SETS UP FOR WM
	MOVEI	T1,11400	;MAKE MICROINTR.(MOVEI MEM MA+1)
	PUSHJ	P,XI		;EXECUTE INSTR. IN T1
	SOJG	Q1,.-1		;DO IT AGAIN
	PUSHJ	P,POSWM		;RESTORE LOC 0 OF CRAM
	TELLCR	<Clearing DX20>
	POPJ	P,		;THEN, RETURN


;HERE TO LOAD THE DX20
LOAD20:	PUSHJ	P,GETLIN	;GET LOAD LINE FROM FILE
				; T1/ WORD COUNT, T2/ LOAD ADDR.
	JUMPE	T1,LDEND	; 0 WC MEANS LAST LINE
	MOVN	Q1,T1		;NEGATE WORD COUNT
	HRLZ	Q1,Q1		;SET UP INDEX FOR LOADING LOOP
	SKIPN	CFLAG		;SKIP IF CRAM LOAD LINE
	JRST	LDWM		;JUMP IF WM LOAD LINE
	PUSH	P,T2		;SAVE OLD LOAD ADDR. ON TOP OF STACK
LDDX1:	MOVE	T2,(P)		;GET BACK OLD LOAD ADDR. FROM STACK
	HRRZ	T3,Q1		;GET OFFSET IN T3
	ADD	T2,T3		;ADJUST CURRENT LOAD ADDR.
	PUSH	P,T2		;REMEMBER PC
	PUSHJ	P,PRECR		;SETS UP PC FOR CRAM, T2/ LOAD ADDR.
	MOVE	T2,LINDAT(Q1)	;GET DATA WORD
	POP	P,T3		;GET ADDRESS TO LOAD
	CAIN	T3,MAGICA	;IS IT THE ADDRESS WHERE
				; THE MAGIC VALUE GETS STORED?
	SKIPE	A.DX20		;AND CONTROLLER A TX02?
	CAIA			;NO
	MOVEI	T2,MAGICV	;YES,
	ANDI	T2,177777	;MAKE SURE 16 BITS
	MOVEI	T3,DXDR0	;SELCT IR
	PUSHJ	P,WTRGX		;LOAD CRAM FROM IR
	AOBJN	Q1,LDDX1	;LOOP BACK
	POP	P,T2		;TAKE IT OFF STACK
	JRST	LOAD20		;GET NEXT LINE
;LOAD WORKING MEMORY FOR WM LOAD LINE
LDWM:	PUSHJ	P,PREWM		;SETS UP MA FOR WM LOADING
LDWM1:	MOVE	T1,LINDAT(Q1)	;GET DATA WORD
	ANDI	T1,377		;MAKE SURE 8 BITS
	TRO	T1,11400	;MAKE MICROINTR. (MOVEI MEM MA+1)
	PUSHJ	P,XI		;EXECUTE MICRO INTR.
	AOBJN	Q1,LDWM1	;BACK FOR NEXT WORD
	PUSHJ	P,POSWM		;RESTORE LOC 0 OF CRAM
	  JRST LOAD20		;FOR THE NXT LINE

LDEND:	SKIPE	T2		;NON-0 DX20 STARTING ADDR.?
	MOVEM	T2,A.STRT	;YES, STORE IT
	DMOVE	T1,FILNAM
	MOVE	T4,DIRECT	;LOOKUP THE FILE AGAIN
	LOOKUP	CHI,T1		; IN ORDER TO DO THE VERIFY
	  ERROR	<Second LOOKUP on file failed>
				;FALL INTO VERIFY CODE


VRFDX:	PUSHJ	P,GETLIN	;GET LOAD LINE FROM FILE
				; T1/ WORD COUNT, T2/LOAD ADDR
	JUMPE	T1,VRFEND	;LAST LINE READ FROM FILE
	MOVN	Q1,T1		;NEGATE WORD COUNT INTO Q1
	HRLZ	Q1,Q1		;SETS UP INDEX FOR VERIFY LOOP
	SKIPN	CFLAG		;SKIP, IF GOT CRAM LOAD LINE
	JRST	VRFWM		;JUMP, IF WM LOAD LINE
	PUSH	P,T2		;SAVE OLD LOAD ADDR. ON STACK
VRFDX1:	MOVE	T2,(P)		;GET BACK OLD LOAD ADDR. FROM STACK
	HRRZ	T3,Q1		;GET OFFSET TO LOAD
	ADD	T2,T3		;ADJUST CURRENT LOAD ADDR.
	ANDI	T2,7777		;MAKE SURE 12 BIT PC
	PUSH	P,T2		;REMEMBER PC
	TRO	T2,IR.EN+PC.EN+PC.AI	;SET BITS FOR READ
	MOVEI	T3,DXDR1	;SELCT PC
	PUSHJ	P,WTRGX		;WRITE PC
	MOVEI	T3,DXDR0	;SELCT IR
	PUSHJ	P,RDRGX		;READ CRAM FROM IR
	MOVE	T2,LINDAT(Q1)	;GET DATA WORD
	POP	P,T3		;GET ADDRESS TO LOAD
	CAIN	T3,MAGICA	;IS IT THE ADDRESS WHERE
				; THE MAGIC VALUE GETS STORED?
	SKIPE	A.DX20		;AND CONTROLLER A TX02?
	CAIA			;NO
	MOVEI	T2,MAGICV	;YES,
	ANDI	T2,177777	;MAKE SURE 16 BITS
	MOVEI	T4,[ASCIZ/CRAM/] ;MESSAGE IN CASE OF ERROR
	CAME	T2,T1		;VERIFY CRAM WORD
	PUSHJ	P,VRFTYP	;GIVE DATA
	MOVEI	T3,DXDR7	;SELCT MBRA37
	PUSHJ	P,RDRGX		;READ IT IN
	TRNE	T1,IR.PER	;CHECK IF IR PARITY ERROR
	ERROR	<CRAM parity error during verification>
	AOBJN	Q1,VRFDX1	;LOOP BACK FOR NEXT WORD
	POP	P,T2		;CLEAN THE STACK
	JRST	VRFDX		;BACK FOR NEXT LINE
;VERIFY WORKING MEMEORY AGAIN WM LOAD LINE
VRFWM:	PUSH	P,T2		;SAVE LOAD ADDR
	PUSHJ	P,PREWM		;SETS UP WORKING MEMORY
VRFWM1:	
	MOVEI	T3,DXDR5	;SELCT DXDR5 HAS WM BYTE
	PUSHJ	P,RDRGX		;READ WM ,AT LOC. C(MA), IN T1
	ANDI	T1,377		;ONLY 8 BITS
	MOVE	T2,LINDAT(Q1)	;GET DATA WORD
	MOVE	T3,0(P)		;GET BASE LOAD ADDRESS BACK
	ADDI	T3,(Q1)		;OFFSET TO CURRENT WORD
	MOVEI	T4,[ASCIZ/Working memory/] ;MESSAGE FOR ERROR
	CAME	T2,T1		;VERIFY WM WORD
	PUSHJ	P,VRFTYP	;TELL OF ERROR
	AOBJN	Q1,VRFWM2	;GET READY FOR NEXT WM WORD
	POP	P,(P)		;BRING STACK INTO PHASE
	PUSHJ	P,POSWM		;RESTORE LOC 0 OF CRAM
	  JRST VRFDX		;GET NEXT LINE
VRFWM2:	MOVEI	T1,1400		;MAKE MICROINTR. (MOVEI NOOP MA+1)
	PUSHJ	P,XI		;INCREMENT MA
	  JRST VRFWM1		;BACK FOR NEXT WORD
VRFEND:
;	SKIPN T2		;IF T2 IS 0,
;	MOVEI T2,1		;TAKE DEFAULT STARTING ADDR.=1
;	CAME T2,STALOC		;VERIFY DX20 STARTING ADDR.
;	JRST ERR16		;ERROR, NOT MATCH

	SKIPE	VERERR		;ANY VERIFY ERRORS?
	ERROR	<Verify error>
	PREWT	(DXDR1)		;SELCT PC
	TRO	T2,PC.EN+IR.EN	;SET BITS
	PUSHJ	P,WTRGX		;SET PC TO 0
	MOVEI	T3,DXDR0	;SELCT IR
	PUSHJ	P,RDRGX		;GET LOC. 0 OF CRAM
	MOVE	Q1,T1		;SAVE IT IN Q1
	SKIPGE	P2,A.STRT	;LOOK FOR STARTING ADDRS
	MOVE	P2,A.LOAD	;...
	CAIN	P2,V.STRT	;DEFAULT (DX10) START ADDR?
	MOVEI	P2,1		;YES, SUBSTITUTE DEFAULT DX20 START
	SKIPG	P2		;ONE SPECIFIED?
	MOVEI	P2,1		;DEFAULT START ADDR IS 1
	SKIPL	A.LOAD		;LOAD ONLY?
	MOVEI	P2,0		;YEP
	SKIPE	P2		;SHOULD WE START IT
	PUSHJ	P,STADX		;YES - TRY TO
	SKIPN	P2		;GIVE CORRECT MESSAGE
	TELLCR	DX20 loaded.
	SKIPE	P2
	TELLCR	DX20 started.
	CLOSE	CHI,		;TERMINATE INPUT CHL
	RELEAS	CHI,
	PUSHJ	P,PVERSN	;PRINT CONFIG INFO
	JRST	GOHOME		;WHEW


;PVERSN - PRINTS VERSION & EDIT NUMBER OF MICRO-CODE ON TERMINAL
;
;	CALL PVERSN
;

PVERSN:	OUTSTR	[ASCIZ /Micro code version /]
	LDB	T1,VR.NUM
	PUSHJ	P,LOCT
	OUTSTR	[ASCIZ /(/]
	LDB	T1,ED.NUM
	PUSHJ	P,LOCT
	OUTSTR	[ASCIZ /)
/]
	POPJ	P,


;VRFTYP - GIVE DATA ON VERIFICATION ERRORS
;T1/DATA READ FROM MEMORY OF DX20
;T2/DATA READ FROM FILE
;T3/ADDRESS OF ERROR
;T4/MESSAGE PREFIX ADDRESS
;	CALL	VRFTYP

VRFTYP:	OUTSTR	[ASCIZ/? /]
	OUTSTR	(T4)		;APPEND DESCRIPTION FROM CALLER
	OUTSTR	[ASCIZ/ verification error at /]
	PUSH	P,T2		;SAVE GOOD DATA
	PUSH	P,T1		;SAVE BAD DATA
	MOVE	T1,T3		;GET ADDRESS
	PUSHJ	P,L6OCT		;PRINT ADDRESS
	OUTSTR	[ASCIZ/, has /]
	POP	P,T1		;GET BAD DATA
	PUSHJ	P,L6OCT		;TYPE IT
	OUTSTR	[ASCIZ/, should have /]
	POP	P,T1		;GET GOOD DATA
	PUSHJ	P,L6OCT		;TYPE IT
	OUTSTR	[ASCIZ/
/]
	SETOM	VERERR		;SET ERROR FLAG
	POPJ	P,		;AND RETURN
;STADX - STARTS THE MICRO-CODE IN DX20
;
;	CALL STADX
;

STADX:	PREWT	(DXMTR)		;STOP MICROPROCESOR
	PUSHJ	P,WTRGX		;
	MOVE	T2,P2		;GET STARTING ADDR. FOR MICROCODE
	TRO	T2,PC.EN+PC.AI+IR.EN	;SET BITS
	MOVEI	T3,DXDR1	;SELECT  PC
	PUSHJ	P,WTRGX		;SET PC TO START ADDR.
	PREWT	(DXMTR)		;SELCT DXMTR
	TRO	T2,MP.STA	;SET START BIT
	PUSHJ	P,WTRGX		;START MICRO-PROCESSOR
	POPJ	P,		;RETURN
;GETLIN - READS IN A LINE OF DATA WORDS TO BE LOADED INTO CRAM OR
; WORKING MEMORY
;
;	CALL GETLIN
;
; RETURN+1: ALWAYS
; LINDAT IS THE TALBE WHICH HAS THE CONVERTED DATA WORDS
; T1/ WORD COUNT OF DATA WORDS IN THE TABLE
; T2/ LOAD ADDR
; CFLAG PROPERLY SET, 1S=DATA WORDS FOR CRAM, 0= FOR WORKING MEMORY
; USES P1 AS PTR, P2 AS LOOP INDEX
GETLN0:	PUSHJ	P,GETC
	CAIE	P1,12
	JRST	GETLN0

GETLIN:	MOVE	T4,[LINWC,,LINWC+1]	;INITIALIZE WORK AREA
	SETZM	LINWC		;
	BLT	T4,CHKSUM
	MOVEI	T3,^D32*5	;MAXIMUN NUMBER OF CHAR.S
	SETZM	CFLAG#		;CFLAG=1S MEANS FOR CRAM
	PUSHJ	P,GETC
	CAIN	P1,";"		;IS IT COMMENT LINE?
	JRST	GETLN0		;YES, IGNORE IT
	CAIE	P1,"C"		;CRAM LOAD LINE?
	JRST	GTLNA		;NO, SEE IF WM LOAD LINE
	SETOM	CFLAG		;YES, SET FLAG
	JRST	GTLNB		;JUMP AROUND
GTLNA:	CAIE	P1,"W"		;WM LOAD LINE?
	ERROR	<1st character wrong in dataline>
GTLNB:	PUSHJ	P,GETC		;GET NEXT CHAR.
	CAIE	P1," "		;MUST BE BLANK
	ERROR	<2nd character wrong in dataline>
	PUSHJ	P,GTWRD		;GET NEXT WORD
	ERROR	<format error in dataline>
	MOVEM	T1,LINWC	;SAVE WORD COUNT FOR THE LINE
	MOVEM	T1,CHKSUM	;INITIALIZE CHECKSUM FOR THE LINE
	PUSHJ	P,GTWRD		;GET NEXT WORD
	ERROR	<format error in dataline>
	ADDM	T1,CHKSUM	;UPDATE CHKSUM
	DPB	T1,[POINT 16,LINWC,19]	;SAVE LOAD ADDR.
	MOVSI	P2,-^D32	;SETUP LOOP INDEX FOR SUBSEQUENT WORDS
				; LINDAT HOLDS AT MOST 32 WORDS
GETLI1:	PUSHJ	P,GTWRD		;GET NEXT WORD
	  JRST GETLI2		;LAST WORD, CHKSUM, READ IN T1
	ADDM	T1,CHKSUM	;UPDATE CHKSUM
	MOVEM	T1,LINDAT(P2)	;SAVE DATA WORD
	AOBJN	P2,GETLI1	;LOOP BACK
	ERROR	<too many words in dataline>
GETLI2:	MOVEM	T1,LINDAT(P2)	;SAVE EVEN CHKSUM
	ADD	T1,CHKSUM	;ADD CHKSUM INTO T1
	TRNE	T1,177777	;CHECKSUM SHOULD BE 0
	ERROR	<checksum error in dataline>
	LDB	T1,[POINT 16,LINWC,35]	;WC IN T1
	LDB	T2,[POINT 16,LINWC,19]	;LOAD ADDR. IN T2
	POPJ	P,		;NONSKIP RETURN
;GTWRD - GET A DATA WORD FROM DATLIN WHICH IS A CHAR. STRING
; CONVERT THE ASCIIZED DATA WORD INTO BINARY
;
;	CALL GTWRD
;
; RETURN+1: DATA WORD DELIMITED BY CR
; RETURN+2: DATA WORD DELIMITED BY ,
; T1/ CONVERTED DATA WORD
; USES P1 AS PTR

GTWRD:	SETZ	T1,		;T1 WILL HAVE RESULT DATA
GTWRD1:	PUSHJ	P,GETC
	CAIN	P1,","		;SKIP IF NOT COMMA
	JRST	CPOPJ1		;GOT THE DATA WORD
				;SKIP RETURN
	CAIN	P1,15		;SKIP IF NOT CR
	JRST	GTWRD1		;CR, THROW IT AWAY AND LOOK FOR LF
	CAIN	P1,12
	POPJ	P,		;RETURN, GOT LAST DATA WORD IN LINE
	LSH	T1,6		;MAKE ROOM
	CAIE	P1," "		;SKIP IF BLANK
	DPB	P1,[POINT 6,T1,35]	;PUT IN T1, UNASCIIZED THE BYTE
	JRST	GTWRD1		;GET NEXT CHAR.

;PREWM - SETS UP THE LOAD ADDR. FOR WORKING MEMORY
; ALSO, SAVES LOC. 0 OF CRAM FOR MICROINSTR. EXECUTION
; T2/ LOAD ADDR.
;
;	CALL PREWM
;
; RETURN+1: ALWAYS

PREWM:	MOVEM	T2,WMADR#	;SAVE LOAD ADDR.
	PREWT	(DXDR1)		;SELCT PC
	TRO	T2,IR.EN+PC.EN	;PC=0, SET FLAGS
	PUSHJ	P,WTRGX		;SET PC
	MOVEI	T3,DXDR0	;SELCT IR
	PUSHJ	P,RDRGX		;READ IR FROM CRAM, PC=0
	MOVEM	T1,PC0SAV#	;SAVE LOC. 0
;SET MA & MAEX BITS
	MOVE	T1,WMADR	;GET LOAD ADDR.
	ANDI	T1,377		;MAX. ADDR. 256
	TRO	T1,1000		;MAKE MICROINTR. (MOVEI LOAD MA)
	PUSHJ	P,XI		;SET MA REGISTER
	MOVE	T1,WMADR	;GET LOAD ADDR. AGAIN
	LSH	T1,-^D8		;KEEP 2 MAEX BITS
	TRO	T1,400		;MAKE MICROINTR. (MOVEI LOAD MAEX)
	JRST	XI		;SET MAEX BITS AND RETURN

;POSWM - RESTORES LOC. 0 OF CRAM AFTER WORKING WITH WORKING MEMORY
;
;	CALL POSWM
;
; RETURN+1: ALWAYS

POSWM:	PREWT	(DXDR1)		;SELCT PC
	TRO	T2,PC.EN+MS.EN	;PC=0
	PUSHJ	P,WTRGX		;SET PC
	MOVE	T2,PC0SAV	;GET C(LOC 0 OF CRAM)
	MOVEI	T3,DXDR0	;SELCT IR
	JRST	WTRGX		;WRITE CRAM FROM IR
				; AND RETURN
;PRECR - SETS UP PC FOR LOADING OR VERIFYING CRAM
; T2/ LOAD ADDR.
;
;	CALL PRECR
;

PRECR:	ANDI	T2,7777		;MAKE SURE 12 BITS PC
	TRO	T2,MS.EN+PC.EN+PC.AI	;SET BITS
	MOVEI	T3,DXDR1	;SELCT PC
	JRST	WTRGX		;WRITE PC AND RETURN

;XI - EXECUTE INSTR. IN T1
;
;	CALL XI
;
; RETURN+1: ALWAYS
; CHANGES T2,T3,&T4
; PRESERVES T1

XI:	PREWT	(DXMTR)		;SELCT DXMTR
	TRO	T2,MP.SC	;CLEAR START BIT & SET SINGLE CYCLE BIT
	PUSHJ	P,WTRGX		;STOP MICROPROCESSOR
	PREWT	(DXDR1)		;CLR PC
	TRO	T2,PC.EN+MS.EN	; AND SET BITS
	PUSHJ	P,WTRGX		;DO IT
	PREWT	(DXDR0)		;LOAD IR WITH INSTR.
	MOVE	T2,T1		; AND LOAD IT IN LOC. 0, ALSO
	PUSHJ	P,WTRGX		;
	PREWT	(DXDR1)		;SELCT PC REG.
	TRO	T2,IR.EN+PC.AI	;SET IR.EN & PC.AI BIT
	PUSHJ	P,WTRGX		;PC HAS 0
	PREWT	(DXMTR)		;READY TO EXECUTE
	TRO	T2,MP.SC+MP.STA	;SET SINGLE STEP & START BITS
	PUSHJ	P,WTRGX		;GO START MICROCONTROLLER
	PREWT	(DXMTR)		;CLEAR START BIT
	TRO	T2,MP.SC	;LEAVE SINGLE CYCLE BIT ON
	JRST	WTRGX		;DO IT AND RETURN
SUBTTL MODULE FOR RH20 HANDLING ROUTINES

;DEVXCT - EXECUTES IOT(INPUT/OUTPUT TRANSFER INSTR.) FOUND AT CALL+1
; T3/ DEVICE CODE
;
;	CALL DEVXCT
; RETURN+1: ALWAYS

DEVXCT:	MOVE	T4,@(P)		;FETCH IOT
	IOR	T4,T3		;GET DEVICE CODE
	XCT	T4		;EXECUTE IT
	JRST	CPOPJ1		;RETURN - SKIP OVER IOT INTR.

;WTREG - WRITES INTERNAL OR EXTERNAL REGISTER
; T3/ REGISTER SELECT NUMBER
; T4/ DRIVE NUMBER
; T2/ BIT 18-35 ARE SPECIFIED
;  
;	CALL WTREG
; RETURN+1:ALWAYS	
; DESTROYS T2

WTREG:	DPB	T3,DO.RS	;SET RS FIELD BIT 0-5 IN T2
	TLO	T2,(DO.LR)	;SET LR LOAD	
	JUMPL	T2,WTREG1	;JUMP IF INTERNAL REG.
	TLO	T2,<(DO.DRE)>(T4)	;SET DRAES BIT & DRIVE NUMBER
				;DO.EP BIT 0 ALREADY
WTREG1:	XCT	RH2DTO		;WRITE IT
	PUSH	P,T1		;SAVE T1
	XCT	RH2CNI		;GET CONI
	TRNE	T1,CI.RAE	;WAS RAE ERROR?
	JRST	WTREG2		;YES, JUMP
	POP	P,T1		;RESTORE T1
	POPJ	P,		;JUST RETURN

WTREG2:	MOVE	T2,T1		;READY TO CLEAR RAE
	ANDI	T2,CO.RAE+CO.ATE+CI.PIA	;SET CONO BITS
	XCT	RH2CNO		;DO CONO
	WARNCR	<RAE error on write to RH20>
	POP	P,T1		;RESTORE T1
	POPJ	P,		;RETURN

;WTRGX - SAME AS WTREG, EXCEPT DRVNUM HAS DRIVE NUMBER

WTRGX: MOVE T4,DRVNUM		;GET DRIVE NUMBER
	JRST	WTREG		;WTREG DOES THE REST OF WORK

;RDREG - READS INTERNAL OR EXTERNAL REGISTER
; T3/ REGISTER NUMBER
; T4/ DRIVE NUMBER
; 
;	CALL RDREG
;
; RETURN+1: ALWAYS
; T1 GETS VALUE

RDREG:	SETZB	T2,T1		;CLEAR THEM
	DPB	T3,DO.RS	;SET REGISTER SELECT
				; DO.LR IS 0 ALREADY
	JUMPL	T2,RDREG1	;JUMP ,IF INTERNAL
	TLO	T2,<(DO.DRE)>(T4)	;SET DRAES BIT & DRIVE NUMBER
				;DO.EP BIT 0 ALREADY
RDREG1:	XCT	RH2DTO		;SET PREPARATION REGISTER
	XCT	RH2DTI		;READ IN T1
	PUSH	P,T1		;SAVE RESULT
	XCT	RH2CNI		;GET CONI IN T1
	TRNE	T1,CI.RAE	;WAS RAE ERROR?
	JRST	RDREG2		;YES, JUMP
	JUMPL	T2,RDEXIT	;JUMP,IF INTERNAL REGISTER
	POP	P,T1		;GET RESULT
	TLNN	T1,(DI.CPE)	;CONTROL BUS PAR ERROR?
	TLNN	T1,(DI.TRA)	;OR NOT TRA(TRA=0)
	JUMPN	T1,RDREG3	;ERROR, JUMP IF AN RH20 EXISTS
RDEXIT:	ANDI	T1,177777	;CLEAR OUT GARBAGE
	POPJ	P,		;RETURN
RDREG2:	MOVE	T2,T1		;GET CONI BITS IN T2
	ANDI	T2,CO.RAE+CO.ATE+CI.PIA	;SET CONO BITS
	XCT	RH2CNO		;DO CONO
	TRNN	F,DR.CHK	;IS CHECKING FOR DRIVE?
	WARNCR	<RAE error on read of RH20>
	POP	P,T1		;RESTORE RESULT
	JRST	RDEXIT		;RETURN
	
RDREG3:	PUSH	P, T1		;SAVE RESULT AGAIN
	WARNCR	< CPE or TRA error on read of RH20>
	POP	P,T1		;RESTORE RESULT
	JRST	RDEXIT		;EXIT

;RDRGX - SAME AS RDREG, EXCEPT DRVNUM HAS DRIVE NUMBER

RDRGX:	MOVE	T4,DRVNUM	;GET DRIVE NUMBER
	JRST	RDREG		;RDREG DOES THE WORK
;CHKDRV - CHECK IF SPECIFIED DRIVE ON GIVEN RH20 IS DX20
; T4/ DRIVE NUMBER
;
;	CALL CHKDRV
;
; RETURN+1: FAIL RETURN, NOT DX20
; RETURN+2: SUCCESS RETURN

CHKDRV:	MOVEI	T3,DXDTR	;GET REGISTER NUMBER
	TRO	F,DR.CHK	;MARK CHECKING FOR DRIVE
	PUSHJ	P,RDREG		;READ DRIVE TYPE REGISTER
	TRZ	F,DR.CHK	;RESET THE MARK FLAG
	MOVE	T2,A.DX20	;GET TYPE OF DX20
	SKIPN	T3,A.TYPE	;IF NO /TYPE GIVEN
	MOVE	T3,TYPTAB(T2)	;USE DEFAULT FOR THIS CONTROLLER TYPE
	LDB	T2,DT.TYP	;GET TYPE IN T2
	CAME	T2,T3		;SKIP IF DX20
	POPJ	P,		;FAIL, RETURN
	JRST	CPOPJ1		;SUCCESS SKIP RETURN

SUBTTL ROUTINES TO PRINT RHNUM AND DRVNUM

;PRHDRV - PRINTS OUT RHNUM FOR RH20, DRVNUM FOR DX20
;	CALL PRHDRV
; RETURN+1:ALWAYS

PRHDRV:	OUTSTR	[ASCIZ/
DX20 Selected: RH20=/]
	MOVE	T1,RHNUM	;GET C(RHNUM)
	PUSHJ	P,LOCT		;TYPE IT
	OUTSTR	[ASCIZ/ DX20=/]
	MOVE	T1,DRVNUM	;GET C(DRVNUM)
	PUSHJ	P,LOCT		;TYPE IT
	OUTSTR	[ASCIZ /
/]
	POPJ	P,
SUBTTL STORAGE
	XLIST	;LITERALS
	LIT
	LIST

;TABLES INDEXED BY THE TYPE SPECIFIED BY THE /DX20 SWITCH.  TX02
;MUST BE THE FIRST ENTRY IN THE TABLE
FILTAB:	SIXBIT/DXMCA/		;DX20/TX02 UCODE IS IN DXMCA.ADX
TX2OFS==.-FILTAB-1
	SIXBIT/DXMCD/		;DX20/RP20 UCODE IS IN DXMCD.ADX
TYPTAB:	EXP	TY.DX2		;DX20/TX02 DRIVE TYPE IS 60
	EXP	TY.RP2		;DX20/RP20 DRIVE TYPE IS 61
HEDPNT:	BLOCK	1		;POINTER FOR CONSTRUCTING HEADER
HEADER:	BLOCK	^D20		;BLOCK FOR HEADER
HEDEND:

CCINT:	EXITX		;^C INTERCEPT BLOCK
	1B34
CCINTP:	BLOCK	1
	BLOCK	1

;DX10 IOT'S

PDCBAS:	PHASE	0
PDCCNO:! CONO PDC,(T1)
PDCCNI:! CONI PDC,T1
PDCDTO:! DATAO PDC,T1
PDCDTI:! DATAI PDC,T1
	DEPHASE

PDC2BS:	CONO	PDC2,(T1)
	CONI	PDC2,T1
	DATAO	PDC2,T1
	DATAI	PDC2,T1

;BYTE POINTERS INTO MEM8

MPNTR:	POINT	12,MEM8
	POINT	12,MEM8,11
	POINT	12,MEM8,23

OCHLOC:	TTOCH		;PRINT SWITCH

FWAZER:!		;START OF AREA TO CLEAR
A.TYPE:	BLOCK	1
PDLST:	BLOCK	PDSIZ+1
DEV:	BLOCK	1		;DEVICE
NAME:	BLOCK	1		;FILE NAME
EXT:	BLOCK	1		;FILE EXTENSION,,-1 IF . SEEN
DIRECT:	BLOCK	1		;DIRECTORY
DIRPTH:	BLOCK	9		;SFD PATH

INHDR:	BLOCK	3		;INPUT HEADER
OUTHDR:	BLOCK	3		;OUTPUT HEADER
RH2CNI:	BLOCK	1		;STORE IOT'S
RH2CNO:	BLOCK	1
RH2DTI:	BLOCK	1
RH2DTO:	BLOCK	1
XRHNUM:	BLOCK	1		;SAVE THE RH20 NUMBER HAS THE DX20
XRHCNI:	BLOCK	1		;IO INSTR. FOR THE RH20 HAS THE DX20
XRHCNO:	BLOCK	1
XRHDTI:	BLOCK	1
XRHDTO:	BLOCK	1
LINWC:	BLOCK	1		;LOAD ADDR,,WORD COUNT OF DATA LINE
LINDAT:	BLOCK	^D32		;SO MANY DATA WORDS
CHKSUM:	BLOCK	1		;CHECKSUM FOR DATALINE FROM FILE
FILNAM:	BLOCK	2
ADDRES:	BLOCK	1
VERERR:	BLOCK	1		;FLAG FOR ADDRESS CHECKING
SW8:	BLOCK	1		;PLACE TO REMEMBER PDP-8 CONSOL SWITCHES
BINFLG:	BLOCK	1		;BIN/RIM FLAG
PISAVE:	BLOCK	1		;PLACE TO SAVE DX10 STATUS
APNTR:	BLOCK	1		;POINTER TO MEM8
FEATUR:	BLOCK	1		;FEATURE REGISTER
VERMP:	BLOCK	1		;VERSION # OF MICRO-CODE
EDTMP:	BLOCK	1		;EDIT LEVEL OF MICRO-CODE
FIRZER:	BLOCK	1		;FIRST LOCATION OF ZEROS
LASZER:	BLOCK	1		;LAST ..
A8FLG:	BLOCK	1		;0 := .BIN FILE, -1 := .A8 FILE
MEM8:	BLOCK	^D4096/3+1	;PDP-8 MEMORY

LWAZER==.-1		;END OF AREA TO CLEAR

FWAONE:!		;START OF AREA TO PRESET TO -1
A.CLR:	BLOCK	1		;/CLEAR:N
A.DUMP:	BLOCK	1		;/DUMP:N
A.END:	BLOCK	1		;/END:N
A.LOAD:	BLOCK	1		;/LOAD:N
A.STRT:	BLOCK	1		;/START:N
A.CHL:	BLOCK	1		;/UNIT:N
A.CPU:	BLOCK	1		;/CPU:N
A.DX10:	BLOCK	1		;/DX10
A.DX20:	BLOCK	1		;/DX20:TYPE
LWAONE==.-1		;END OF AREA TO PRESET TO -1

	END	START