Google
 

Trailing-Edge - PDP-10 Archives - BB-H138D-BM - 5-1-sources/dx20ld.mac
There are 17 other files named dx20ld.mac in the archive. Click here to see a list.
; UPD ID= 1684, SNARK:<5.UTILITIES>DX20LD.MAC.4,  12-Mar-81 11:45:07 by GRANT
;Update Copyright
; UPD ID= 1578, SNARK:<5.UTILITIES>DX20LD.MAC.3,  24-Feb-81 16:59:28 by BLOUNT
; UPD ID= 1215, SNARK:<5.UTILITIES>DX20LD.MAC.2,  31-Oct-80 07:38:56 by UHLER
;TCO 5.1185 SET GJ%OLD IN GTJFN FOR MICROCODE TO INSURE WE FIND THE FILE.
; UPD ID= 375, SNARK:<4.1.UTILITIES>DX20LD.MAC.2,  26-Mar-80 13:46:11 by DBELL
;TCO 4.1.1123 - ADD /R AND /T SWITCHES AND ADD SUPPORT FOR LOADING
; DX20S WHICH RUN RP20 DISKS
;<4.UTILITIES>DX20LD.MAC.3, 24-Oct-79 18:32:04, EDIT BY DBELL
;TCO 4.2542 - TYPE LOCATION AND DATA OF MISMATCHES DURING VERIFICATION
;<4.UTILITIES>DX20LD.MAC.2, 10-Mar-79 13:52:07, EDIT BY KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<4.UTILITIES>DX20LD.MAC.1, 23-Jan-79 15:42:38, Edit by KONEN
;UPDATE VERSION NUMBER FOR RELEASE 4
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE ANY MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976,1977,1978,1979,1980,1981 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.

TITLE	DX20LD - DECSYSTEM-20 PROGRAM TO LOAD, VERIFY, AND START A DX20

	SUBTTLE E.OUYANG/EGF 31-MAY-78

	SEARCH MONSYM,MACSYM

	.REQUIRE SYS:MACREL

	IFNDEF .PSECT,<.DIRECT .XTABM>	;MAKE IT WORK W/H MACRO(50)

	SALL

	PGVER. 5,0,5,0
; AC ASSIGNMENT

F=0
T1=1
T2=2
T3=3
T4=4
Q1=5
Q2=6
Q3=7
P1=10
P2=11
P3=12
P4=13
P5=14
P6=15
CX=16
P=17

;PERMANANT REGISTER ASSIGNMENT

RHNUM==P5			;P5 HAS THE RH20 NUMBER
DRVNUM==P6			;P6 HAS THE DRIVE NUMBER FOR THE DX20

;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

;FLAG DEFINITION FOR SWITCHES IN THE COMMAND(1 = SWITCH GIVEN)

	CLEAR==:1B0		;CLEAR SWITCH
	DRIV==:1B1		;/^D SWITCH
	LOD==:1B2		;/^L SWITCH
	START==:1B3		;/^S SWITCH
	VERIFY==:1B4		;/^V SWITCH
	EOCFLG==:1B5		;=1 IF END-OF-CMD REACHED

	DXFND==:1B6		;1=FOUND ONE DX20 ALREADY
	DR.CHK==:1B7		;1=IS CHECKING A DRIVE
	XIT==:1B8		;/^E SWITCH (EXIT)
	F.DISK==:1B9		;DX20 MUST BE RP20 VERSION
	F.TAPE==:1B10		;DX20 MUST BE TU7X VERSION

;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

DEFSTR(DO.RS,T2,5,6)		;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.DXA==60			;DX20-A DRIVE TYPE (FOR TU7X TAPES)
TY.DXB==61			;DX20-B DRIVE TYPE (FOR RP20 DISKS)

;FIELD DEFINITION FOR DX20 REGISTERS

DEFSTR(DT.TYP,T1,^D35,^D9)	;TYPE FIELD IN DRIVE TYPE REGISTER

;MACROS DEFINE STRUCTURE FOR EDIT AND VERSION NUMBER IN Q1

DEFSTR(ED.NUM,Q1,^D35,^D10)	;FIELD FOR EDIT NUMBER IN Q1
DEFSTR(VR.NUM,Q1,^D25,^D6)	;FIELD FOR VERSION NUMBER IN Q1
	SUBTTL MAIN MODULE

;MAIN PROGRAM STARTS HERE

BEGIN:	RESET			;RESET THE WORLD
	MOVE P,[IOWD PDLTH,STAK] ;SETUP STACK FOR SUBROUTINE CALLS
	MOVEI T1,.FHSLF		;GET PROCESS HANDLE
	RPCAP			;GET CAPABILITY WORD
	  ERJMP FATAL		;JUMP IF ERROR
	TXO T3,SC%OPR		;ENABLE OPERATOR CAPABILITY
	EPCAP			;ENABLE IT
	  ERJMP FATAL		;JUMP, IF ERROR
	USRIO			;GET USER I/O PRIVIELEGE
	  ERJMP FATAL		;UNABLE TO GET THE PRIVILEGE
	CALL INCMD		;INPUT OPERATOR COMMAND
	CALL XCMD		;PROCESS THE COMMAND
	JRST BEGIN		;DO IT AGAIN

FATAL:	JSERR			;PRINT JSYS ERROR
	HALTF			;EXIT TO MONITOR BECAUSE FATAL
	JRST BEGIN		;RESTART IF CONTINUE
				; END OF MAIN LOOP
	SUBTTL COMMAND INPUT MODULE

;MODULE TO INPUT AND PARSE THE OPERATOR COMMAND

INCMD:	SETZB F,CMDBUF		;CLEAR CMDBUF AND FLAGS
	SETZM JFN		;NO JFN ANYMORE
	MOVE T4,[XWD CMDBUF,CMDBUF+1] ;SETUP T4
	BLT T4,FILNAM+BUFLEN-1	;ZERO THEM OUT
	HRROI T1,PROMPT		;PROMP MSG POINTER IN T1
	PSOUT			;PRINT MSG ON TTY
	  ERJMP JERR1		;JUMP IF ERROR
	HRROI T1,CMDBUF		;POINTER TO COMMAND BUFFER
	MOVX T2,RD%CRF!RD%RAI	;RETURN LF AND CONVERT LOWER TO UPPER
	HRRI T2,BUFLEN*5	;MAX. # OF CHAR.'S IN RH OF T2
	HRROI T3,PROMPT		;PROMPT MSG FOR ^R
	RDTTY			;INPUT COMMAND FROM TERMINAL
	  ERJMP JERR2		;JUMP IF ERROR
;	TXNE T2,RD%BLR		;BACKUP LIMIT FOR EDITING REACHED?
;	JRST ERR1		;YES,JUMP
	TXNN T2,RD%BTM		;TOO MANY CHAR.'S IN COMMAND?
	JRST ERR2		;YES,JUMP
	MOVEI T1,1		;INITIALIZE STARTING ADDR. FOR
	MOVEM T1,STALOC		; MICRO-CODE IN THIS FILE
	HRROI T1,DEFEXT		;POINTER TO THE DEFAULT FILE TYPE
	MOVEM T1,JFNBLK+.GJEXT	;PUT POINTER WHERE OPNFIL WILL FIND IT
	MOVX T1,GJ%OLD		;WE WANT AN EXISTING FILE
	MOVEM T1,JFNBLK+.GJGEN	;STORE FLAG IN BLOCK
	MOVE Q1,[POINT 7,CMDBUF, ] ;POINTER TO COMMAND BUFFER IN Q1
	MOVE Q2,[POINT 7,FILNAM, ] ;FILNAM WILL HAVE THE FILENAME
				; POINTER TO FILNAM IN Q2

;LOOP STARTS HERE TO RETRIVE FILENAME, IF THERE IS ONE 

GTFN:	ILDB CX,Q1		;GET CHAR. IN CX
	CAIE CX,"/"		;END OF FILENAME?
	JRST GTFN1		;NO,JUMP
	SKIPE FILNAM		;WAS FILENAME GIVEN?
	CALL OPFIL		;YES,OPEN IT
	  JRST GTSW		;GO GET SWITCHES
GTFN1:	CAIE CX,012		;LINE FEED TERMINATES COMMAND
	JRST GTFN2		;NO,JUMP
	SKIPN FILNAM		;WAS FILENAME GIVEN?
	JRST INCMD		;GO PROMPT AGAIN
	CALL OPFIL		;YES,OPEN IT
	  JRST CMDEN1		;GO SET FLAGS
GTFN2:	IDPB CX,Q2		;STNBE CHAR. FOR FILENAME
	JRST GTFN		;GO BACK FOR NXT CHAR.

	; ..
	; ..

;LOOP STARTS HERE TO RETRIVE AND PROCESS THE SWITCHES
; IN THE COMMAND. 
; P1&P2 USED AS WORK AREA FOR THE SWITCH WITH POINTER IN Q2
; ASSUME SWITCH HAS < 10 CHAR.'S.

GTSW:	MOVE Q2,[POINT 7,P1, ]	;P1 TO HOLD SWITCH TO BE PROCESSED
	SETZB P1,P2		;CLEAR AREA FOR SWITCH
GTSW1:	ILDB CX,Q1		;GET NXT CHAR.
	CAIN CX,"/"		;SWITCH DELIMITER?
	JRST EXSW		;YES, GOTO PROCESS IT
	CAIE CX,012		;LF END OF COMMAND?
	JRST STOCHR		;NO, STORE CHAR.
	TXO F,EOCFLG		;SET END-OF-CMD FLAG
	JRST EXSW		;GO AND PROCESS SWITCH
STOCHR:	IDPB CX,Q2		;STORE SWITCH
	JRST GTSW1		;GO BACK FOR NXT CHAR.

;EXECUTE THE SWITCH, THE CHAR. STRING, STORED IN P1& P2

EXSW:	MOVE Q2,[POINT 7,P1, ]	;POINTER TO SWITCH STRING IN Q2
	ILDB T1,Q2		;1ST CHAR. IN T1
	ILDB T2,Q2		;2ND CHAR. IN T2
	CAIN T2,":"		;2ND CHAR. = :?
	JRST DSSWI		;MUST BE /^D OR /^S SWITCH, JUMP
	JUMPN T2,ERR3		;IF NOT, SHOULD BE 1-CHAR. SWITCH
	CALL ONESW		;PROCESS ONE CHAR. SWITCH
	  JRST ERR4		;ERROR, INVALID 1-CHAR. SWITCH
	JRST XSWEND		;GOTO END OF SWITCH PROCESSING
DSSWI:	CAIE T1,"D"		;DRIVE SWITCH?
	JRST SSWX		;NO,JUMP
	CALL XDSW		;PROCESS /^D SWITCH
	  JRST ERR5		;ERROR IN /^D SWITCH
	JRST XSWEND		;GOTO END OF SWITCH PROCESSING
SSWX:	CAIE T1,"S"		;MUST BE /^S SWITCH!
	JRST ERR6		;INVALID SWITCH
	CALL XSSW		;PROCESS /^S SWITCH
	  JRST ERR7		;ERROR IN /^S SWITCH
XSWEND:	TXZN F,EOCFLG		;JUST PROCESSED THE LAST SWITCH?
	JRST GTSW		;NO, GO BACK FOR NXT SWITCH

;END OF CMD

CMDEN:	SKIPN FILNAM		;FILENAME GIVEN?
	RET			;**NO,JUST RETURN**
	TXNN F,LOD+VERIFY	;YES, THEN /^L OR /^V SWITCH GIVEN?
CMDEN1:	TXO F,LOD+VERIFY+START	;NONE,ASSUME /^L, /^V, AND /^S SWITCHES
	RET			;EXIT
				; END OF INCMD
SUBTTL COMMAND PROCESSING MODULE
;MODULE TO PROCESS OPERATOR COMMAND

XCMD:	TXZN F,DRIV		;WAS D SWITCH GIVEN?
	CALL LOKDX		;IF NOT, LOOK FOR ONE
	SETZ T2,		;GET READY TO RESET DX20
	MOVEI T3,DXMTR		;GET THE REGISTER
	MOVE T4,DRVNUM		;GET THE DRIVE NUMBER
	TXO T2,DX.RST		;SET THE RESET BIT
	CALL WTREG		;RESET DX20
	TXZE F,CLEAR		;C SWITCH GIVEN?
	CALL CLRDX		;CLEAR DX20'S MEMORY
	SKIPN FILNAM		;FILENAME GIVEN?
	JRST XCMD2		;NO,JUMP
	TXZN F,LOD		;L SWITCH GIVEN?
	JRST XCMD1		;NO,JUMP
	CALL LDDX		;LOAD FILE INTO DX20
	MOVE T1,JFN		;GET JFN
	CLOSF			;CLOSE THE FILE
	  ERJMP JERR6		;ERROR
	CALL OPFIL		;REOPEN FILE FOR VERIFYING
	
XCMD1:	TXZE F,VERIFY		;V SWITCH GIVEN?
	CALL VRFDX		;VERIFY CONTENTS OF DX20 AGAINST
				; SPECIFIED FILE
	MOVE T1,JFN		;GET JFN
	CLOSF			;CLOSE THE FILE
	  ERJMP JERR7		;ERROR
	CALL PVERSN		;PRINT VERSION NUMBER OF FILE ON TTY
XCMD2:	TXZE F,START		;WAS S SWITCH GIVEN?
	CALL STADX		;START DX20 MICROPROCESSOR
	RET			;EXIT
	SUBTTL ROUTINES FOR COMMAND INPUT MODULE


;OPFIL - OPEN FILE FOR INPUT, ONE WORD PER READ
; FILNAM/ FILE NAME, ASCIZ STRING
;
;	CALL OPFIL
;
; RETURN+1: ALWAYS

OPFIL:	MOVX T1,JFNBLK		;POINT TO ARGUMENT TABLE
	HRROI T2,FILNAM		;SPECIFIED FILENAME IN FILNAM
	GTJFN			;GET JFN IN RH(T2)
	  ERJMP JERR3		;ERROR
	MOVEM T1,JFN		;SAVE JFN
	MOVE T2,[7B5+OF%RD+OF%PLN] ;7-BIT BYTES, NOT CHECKING LINE #
	OPENF			;OPEN THE FILE
	  ERJMP JERR4		;OPEN ERROR, CODE IN T1
	RET			;RETURN

;ONESW - IDENTIFY THE ONE-CHAR. SWITCH AND SET ITS FLAG
; T1/ ONE-CHAR. SWITCH RIGHT-JUSTIFIED
;
;	CALL ONESW
;
; RETURN+1: INVALID ONE-CHAR. SWITCH
; RETURN+2: VALID 1-CHAR. SWITCH, OR L OR V SWITCH W/H NO FILENAME

ONESW:	CAIE T1,"C"		;CLEAR SWITCH?
	JRST LSWI		;NO,JUMP
	TXO F,CLEAR		;SET FLAG
	RETSKP		;SKIP RETURN
LSWI:	CAIE T1,"L"		;LOAD SWITCH?
	JRST VSWI		;NO,JUMP
	SKIPN FILNAM		;FILENAME MUST BE GIVEN
	JRST ERR22		;IF NOT, ERROR JUMP
	TXO F,LOD		;YES, SET FLAG
	RETSKP		;SKIP RETURN
VSWI:	CAIE T1,"V"		;VERIFY SWITCH?
	JRST SSWI		;NO,JUMP
	SKIPN FILNAM		;FILENAME MUST BE GIVEN
	JRST ERR22		;IF NOT, ERROR JUMP
	TXO F,VERIFY		;YES,SET FLAG
	RETSKP		;SKIP
SSWI:	CAIE T1,"S"		;START SWITCH?
	JRST ESWI		;NO, GO SEE IF /E
	TXO F,START		;YES,SET FLAG
	RETSKP		;SKIP RETURN
ESWI:	CAIE T1,"E"		;/E (EXIT)
	JRST TSWI		;NO, GO SEE IF /T
	HALTF			;/E EXIT RIGHT NOW
	JRST BEGIN		;IF CONTINUE, RESTART
TSWI:	CAIE T1,"T"		;/T (DX20 MUST BE TU7X VERSION)?
	JRST RSWI		;NO, GO SEE IF /R
	TXNE F,F.DISK		;ALREADY SPECIFIED DISK?
	JRST ERR23		;YEP, LOSE
	TXO F,F.TAPE		;REMEMBER MUST BE A TAPE
	RETSKP			;SKIP RETURN
RSWI:	CAIE T1,"R"		;/R (DX20 MUST BE RP20 VERSION)?
	RET			;NO, ERROR
	TXNE F,F.TAPE		;ALREADY SPECIFIED TAPE?
	JRST ERR23		;YES, LOSE
	TXO F,F.DISK		;REMEMBER MUST BE A DISK
	RETSKP			;SKIP RETURN

;XDSW - PROCESS /^D SWITCH(/D:[M]N)
; WHERE M,N ARE OCTAL DIGITS
; M=RHNUM( 0, IF M IS MISSING) FOR RH20
; N=DRVNUM FOR DX20
; Q2/ PTR TO SWITCH IN P1 & P2
;
;	CALL XDSW
; RETURN+1: ERROR IN /^D SWITCH
; RETURN+2: SUCCESS RETURN
; DESTROYS CX, P5, CHANGES Q2

XDSW:	TXO F,DRIV		;YES,SET FLAG
	SETZB RHNUM,DRVNUM	;INITIALIZE RHNUM,DRVNUM
	ILDB CX,Q2		;GET NXT CHAR
	CALL OCTCNV		;RETURN VALUE IN T1
	  RET			;ERROR, NOT OCTAL
	PUSH P,T1		;SAVE T1
	ILDB CX,Q2		;NXT CHAR.
	JUMPN CX,DSW1		;JUMP, ONLY 1 OCTAL DIGIT GIVEN
	POP P,DRVNUM		;STORE DRIVE NUMBER
	CALL TESDSW		;TEST IF SPECIFIED DX20 EXISTS
	  RETSKP		;GET NEXT SWITCH
DSW1:	POP P,RHNUM		;STORE RH20 NUMBER
	ILDB T1,Q2		;GET NXT CHAR.
	JUMPN T1,R		;ERR. RETURN, > 2 OCTAL DIGITS IN /^D SWITCH
	CALL OCTCNV		;CX HAS OCTAL DIGIT, RETURN VALUE IN T1
	  RET			;ERROR, NOT OCTAL
	MOVEM T1,DRVNUM		;STORE DRIVE NUMBER
	CALL TESDSW		;TEST IF SPECIFIED DX20 EXISTS
	  RETSKP		;GET NEXT SWITCH

;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:	CALL DEFTYP		;DEFAULT DX20 TYPE IF NECESSARY
	MOVE T3,RHNUM		;GET RH20 NUMBER
	CALL CHKRH2		;SPECIFIED RH20 THERE?
	  JRST ERR17		;NO, ERROR JUMP
	MOVE T4,DRVNUM		;GET DRIVE NUMBER
	CALL CHKDRV		;SPECIFIED DRIVE DX20?
	  JRST ERR18		;NO,ERROR JUMP
	CALL PRHDRV		;PRINT OUT DX20 SELECTED
	RET			;GOOD RETURN
;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
	CALL DEVXCT		;GET STATUS BACK
	 CONI 0,T1		; IN T1
	TRNN T1,7		;GET SAME PIA?
	RET			;NO, FAIL RETURN
	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
	RETSKP			;SKIP RETURN

;XSSW - PROCESS /^S SWITCH
; Q2/ PTR TO SWITCH IN P1 & P2
;
;	CALL XSSW
;
; RETURN+1: ERROR IN /^S SWITCH
; RETURN+2: SUCCESS RETURN
; DESTROYS Q3, CX, P6 , CHANGES Q2

XSSW:	TXO F,START		;SET FLAG
	MOVE Q3,[POINT 7,P1, ]	;POINTER TO LOC. P1
	MOVEI P6,^D8		;SHIFT THE NEXT 8 CHAR.'S
SSWX1:	ILDB CX,Q2		;NEXT CHAR.
	IDPB CX,Q3		;SHIFT
	SOJG P6,SSWX1		;NXT CHAR.
	HRROI T1,P1		;DESIGNATOR IN T1
	MOVEI T3,^D8		;RADIX 8
	NIN			;# IN T2
	  ERJMP JERR5
	LDB CX,T1		;CHAR. TERMINATING
	JUMPN CX,R		;ERROR RETURN
	MOVEM T2,STALOC		;STORE STARTING ADDRESS
	RETSKP		;SKIP RETURN

;OCTCNV -  CONVERT 1 OCTAL DIGIT IN CX AND RETURN VALUE TO T1
; CX/ OCTAL DIGIT IN ASCII
;
;	CALL OCTCNV
;
; RETURN+1: ERROR, NOT OCTAL DIGIT
; RETURN+2: GOOD RETURN

OCTCNV:	CAIG CX,"7"		;DIGIT > 7
	CAIGE CX,"0"		; OR < 0
	RET			;ERROR, NOT OCTAL DIGIT
	SUBI CX,60		;GET BINARY VALUE
	MOVE T1,CX		;PUT IN T1
	RETSKP			;SKIP RETURN
SUBTTL ROUTINES FOR COMMAND PROCESSING MODULE
;LOKDX - LOOK FOR THE ONLY ONE DX20 OF THE PROPER TYPE 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:	CALL DEFTYP		;DEFAULT DX20 TYPE IF NECESSARY
	MOVSI Q1,-10		;SETUP COUNTER, AT MOST 10 RH20'S
LOKDX1:	HRRZ T3,Q1		;GET RHNUM
	CALL 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
	CALL CHKDRV		;CHECK DRIVE IF DX20?
	  JRST LOKDX3		;JUMP,NOT THIS DRIVE
	TXOE F,DXFND		;WAS DX20 FOUND?
	JRST ERR19		;YES, ERROR DX20 AMBIGUOUS
	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
	TXZN F,DXFND		;FOUND THE DX20?
	JRST ERR20		;NO, ERROR****DX20 NOT FOUND MSG**
	MOVE RHNUM,XRHNUM	;YES,RESTORE THE RH20 NUMBER
	MOVE T4,[XWD XRHCNI,RH2CNI] ;SETUP T4
	BLT T4,RH2DTO		;RESTORE IO INSTR. FOR THE RH20
	CALL PRHDRV		;PRINT OUT DX20 SELECTED
	RET			;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
	CALL PRECR		;SET IT UP
	PREWT (DXDR0)		;SELCT IR REGISTER
	CALL 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
	CALL PREWM		;SETS UP FOR WM
	MOVEI T1,11400		;MAKE MICROINTR.(MOVEI MEM MA+1)
	CALL XI			;EXECUTE INSTR. IN T1
	SOJG Q1,.-1		;DO IT AGAIN
	CALL POSWM		;RESTORE LOC 0 OF CRAM
	HRROI T1,[ASCIZ/	DX20 Memory Cleared
/]				;PUTOUT MESSAGE
	PSOUT			;
	  ERJMP JERR1
	RET			;THEN, RETURN
;LDDX - LOAD THE FILE, THE MICROCODE, INTO DX20
;
;	CALL LDDX
;
; RETURN+1: ALWAYS
; USES Q1

LDDX:	CALL 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
	CALL 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?
	MOVEI T2,MAGICV		;YES,
	ANDI T2,177777		;MAKE SURE 16 BITS
	MOVEI T3,DXDR0		;SELCT IR
	CALL WTRGX		;LOAD CRAM FROM IR
	AOBJN Q1,LDDX1		;LOOP BACK
	POP P,T2		;TAKE IT OFF STACK
	JRST LDDX		;GET NEXT LINE
;LOAD WORKING MEMORY FOR WM LOAD LINE
LDWM:	CALL 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)
	CALL XI			;EXECUTE MICRO INTR.
	AOBJN Q1,LDWM1		;BACK FOR NEXT WORD
	CALL POSWM		;RESTORE LOC 0 OF CRAM
	  JRST LDDX		;FOR THE NXT LINE

LDEND:	SKIPE T2		;NON-0 DX20 STARTING ADDR.?
	MOVEM T2,STALOC		;YES, STORE IT
	HRROI T1,[ASCIZ/	Microcode Loaded
/]
	PSOUT			;OUTPUT THE MESSAGE
	  ERJMP JERR1		;JUMP IF ERROR
	RET			;RETURN
;VRFDX - VERIFIES THE CONTENTS OF DX20 MEMORY AGAINST THE FILE
;
;	CALL VRFDX
;
; RETURN+1: ALWAYS
; USES Q1

VRFDX:	SETZM VERFLC		;INITIALIZE CRAM MISMATCH COUNTER
	SETZM VERFLW		;AND WORKING MEMORY MISMATCH COUNT
VRFDXL:	CALL 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
	CALL WTRGX		;WRITE PC
	MOVEI T3,DXDR0		;SELCT IR
	CALL 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?
	MOVEI T2,MAGICV		;YES,
	ANDI T2,177777		;MAKE SURE 16 BITS
	CAME T2,T1		;VERIFY CRAM WORD
	CALL VERERR		;ERROR, GO DESCRIBE IT
	MOVEI T3,DXDR7		;SELCT MBRA37
	CALL RDRGX		;READ IT IN
	TXNE T1,IR.PER		;CHECK IF IR PARITY ERROR
	JRST ERR21		;YES, ERROR****CRAM PARITY ERROR
	AOBJN Q1,VRFDX1		;LOOP BACK FOR NEXT WORD
	POP P,T2		;CLEAN THE STACK
	JRST VRFDXL		;BACK FOR NEXT LINE
;VERIFY WORKING MEMEORY AGAIN WM LOAD LINE
VRFWM:	PUSH P,T2		;SAVE LOAD ADDRESS
	CALL PREWM		;SETS UP WORKING MEMORY

VRFWM1:	MOVEI T3,DXDR5		;SELCT DXDR5 HAS WM BYTE
	CALL RDRGX		;READ WM ,AT LOC. C(MA), IN T1
	ANDI T1,377		;ONLY 8 BITS
	MOVE T2,LINDAT(Q1)	;GET DATA WORD
	HRRZ T3,Q1		;GET ADDRESS IN CASE OF FAILURE
	ADD T3,(P)		;ADD BASE ADDRESS
	ANDI T3,7777		;KEEP ONLY 12 BITS
	CAME T2,T1		;VERIFY WM WORD
	 CALL VERERR		;DIDN'T MATCH, COMPLAIN
	AOBJN Q1,VRFWM2		;GET READY FOR NEXT WM WORD
	POP P,T2		;RESTORE AC
	CALL POSWM		;RESTORE LOC 0 OF CRAM
	  JRST VRFDXL		;GET NEXT LINE
VRFWM2:	MOVEI T1,1400		;MAKE MICROINTR. (MOVEI NOOP MA+1)
	CALL 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
	MOVE T2,VERFLW		;GET NUMBER OF WORKING MEMORY MISMATCHES
	ADD T2,VERFLC		;ADD IN CRAM MEMORY MISMATCHES
	JUMPN T2,VRFTOT		;GO IF HAD SOME ERRORS
	HRROI T1,[ASCIZ/	Microcode Verified
/]				;GET GOOD STRING
	PSOUT			;SAY ALL IS WELL
	RET			;DONE


VRFTOT:	HRROI T1,[ASCIZ/
Total of /]			;GET SUMMARY STRING
	PSOUT			;TYPE IT
	MOVEI T1,.PRIOU		;GET READY
	MOVEI T3,^D10		;DECIMAL
	NOUT			;TYPE NUMBER
	 JFCL
	HRROI T1,[ASCIZ/ difference(s) found
/]				;FINAL TEXT
	PSOUT			;TYPE IT
	JRST BEGIN		;START OVER
;VERERR - CALLED WHENEVER A WORD OF THE MICROCODE FAILS TO MATCH
;THE EXPECTED VALUE.  CALL:
;
;	T1/	DATA READ FROM MICROCODE
;	T2/	DATA FROM FILE
;	T3/	ADDRESS
;



VERERR:	PUSH P,T1		;SAVE MICROCODE DATA
	PUSH P,T2		;AND FILE DATA
	SKIPN CFLAG		;IS THIS CRAM OR WORKING MEMORY FAILURE?
	AOSA T2,VERFLW		;WORKING, INCREMENT FAILURES
	AOS T2,VERFLC		;CRAM, INCREMENT FAILURES
	SOJG T2,VERERO		;SEE IF ALREADY GAVE THE HEADER TEXT
	HRROI T1,[ASCIZ/
?Mismatch found in CRAM:/]	;NO, GET STRING
	SKIPN CFLAG		;FOUND IN WORKING MEMORY?
	HRROI T1,[ASCIZ/
?Mismatch found in working memory:/]	;YES, GET OTHER STRING
	PSOUT			;GIVE START OF HEADER
	HRROI T1,[ASCIZ/
Address    File data    DX20 data
/]				;REST OF HEADER
	PSOUT			;TYPE IT
VERERO:	MOVEI T1,.PRIOU		;PRIMARY OUTPUT
	MOVE T2,T3		;GET ADDRESS
	MOVE T3,[NO%LFL+<5,,10>]	;LEADING FILLER FOR FIVE DIGIT OCTAL
	NOUT			;TYPE IT
	 JFCL
	MOVEI T2,"/"		;GET SLASH
	BOUT			;TYPE IT
	POP P,T2		;RESTORE FILE DATA
	MOVE T3,[NO%LFL+<^D12,,10>]	;12 COLUMNS OF OCTAL TO SPACE OVER
	NOUT			;TYPE FILE DATA
	 JFCL
	POP P,T2		;RESTORE MICROCODE DATA
	MOVE T3,[NO%LFL+<^D13,,10>]	;AGAIN
	NOUT			;TYPE NUMBER
	 JFCL
	HRROI	T1,[ASCIZ/
/]				;GET A CRLF
	PSOUT			;FINISH WITH THAT
	RET			;DONE
;PVERSN - PRINTS VERSION & EDIT NUMBER OF MICRO-CODE ON TERMINAL
;
;	CALL PVERSN
;

PVERSN:	PREWT (DXDR1)		;SELCT PC
	TRO T2,PC.EN+IR.EN	;SET BITS
	CALL WTRGX		;SET PC TO 0
	MOVEI T3,DXDR0		;SELCT IR
	CALL RDRGX		;GET LOC. 0 OF CRAM
	MOVE Q1,T1		;SAVE IT IN Q1
	HRROI T1,[ASCIZ/	Microcode Version  /]	; HEADING MESSAGE
	PSOUT			;PRINT MESSAGE ON TERMINAL
	  ERJMP JERR1
	LOAD T2,VR.NUM		;GET VERSION NUMBER
	MOVEI T1,.PRIOU		;OUTPUT DESIGNATOR, TTY
	MOVEI T3,^D8		;RADIX 8
	NOUT			;PRINT THE NUMBER
	  ERJMP JERR12		;ERROR
	HRROI T1,[ASCIZ/ (/]
	PSOUT			;PUT MESSAGE ON TERMINAL
	  ERJMP JERR1
	LOAD T2,ED.NUM		;GET EDIT NUMBER
	MOVEI T1,.PRIOU		;OUTPUT ON TTY
	MOVEI T3,^D8		;RADIX 8
	NOUT			;PRINT VERSION NUMBER
	  ERJMP JERR13		;ERROR
	HRROI T1,[ASCIZ/)
/]				;PUT CLOSE PARENTHESE
	PSOUT
	  ERJMP JERR1
	RET			;RETURN


;STADX - STARTS THE MICRO-CODE IN DX20
;
;	CALL STADX
;

STADX:	PREWT (DXMTR)		;STOP MICROPROCESOR
	CALL WTRGX		;
	MOVE T2,STALOC		;GET STARTING ADDR. FOR MICROCODE
	TRO T2,PC.EN+PC.AI+IR.EN ;SET BITS
	MOVEI T3,DXDR1		;SELECT  PC
	CALL WTRGX		;SET PC TO START ADDR.
	PREWT (DXMTR)		;SELCT DXMTR
	TRO T2,MP.STA		;SET START BIT
	CALL WTRGX		;START MICRO-PROCESSOR
	HRROI T1,[ASCIZ/	DX20 Started at Address /]
	PSOUT			;PUTOUT THE MESSAGE
	  ERJMP JERR1
	MOVX T1,.PRIOU		;OUTPUT TO TTY
	MOVE T2,STALOC		;STARTING ADDRESS
	MOVX T3,<NO%MAG!^D8>	;ALWAYS POSITIVE OCTAL NUMBER
	NOUT			;PRINT THE STARTING ADDR
	 ERJMP JERR1		;ERROR
CRLF:	HRROI T1,[ASCIZ\
\]				;CRLF
	PSOUT			;PRINT CRLF
	 ERJMP JERR1		;ERROR
	RET			;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

GETLIN:	MOVE T4,[LINWC,,LINWC+1] ;INITIALIZE WORK AREA
	SETZM LINWC		;
	BLT T4,CHKSUM
	MOVE T1,JFN		;INPUT FILE JFN
	HRROI T2,DATLIN		;WHERE TO PUT THE CHAR. STRING
	MOVEI T3,^D32*5		;MAXIMUN NUMBER OF CHAR.S
	MOVEI T4,012		;LF MEANS END OF THE LINE
	SIN			;STRING INPUT
	  ERJMP JERR8		;JERR8 OR END OF FILE
	MOVE P1,[POINT 7,DATLIN, ] ;P1 AS THE PTR
	SETZM CFLAG#		;CFLAG=1S MEANS FOR CRAM
	ILDB T1,P1		;GET 1ST CHAR.
	CAIN T1,";"		;IS IT COMMENT LINE?
	JRST GETLIN		;YES, IGNORE IT
	CAIE T1,"C"		;CRAM LOAD LINE?
	JRST GTLNA		;NO, SEE IF WM LOAD LINE
	SETOM CFLAG		;YES, SET FLAG
	JRST GTLNB		;JUMP AROUND
GTLNA:	CAIE T1,"W"		;WM LOAD LINE?
	JRST ERR10		;OTHER CHAR. IS WRONG
GTLNB:	ILDB T1,P1		;GET NEXT CHAR.
	CAIE T1," "		;MUST BE BLANK
	JRST ERR11		;IF NOT, ERROR
	CALL GTWRD		;GET NEXT WORD
	  JRST ERR12		;ERROR RETURN, FORMAT ERROR
	MOVEM T1,LINWC		;SAVE WORD COUNT FOR THE LINE
	MOVEM T1,CHKSUM		;INITIALIZE CHECKSUM FOR THE LINE
	CALL GTWRD		;GET NEXT WORD
	  JRST ERR13		;FORMAT ERROR
	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:	CALL 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
	JRST ERR14		;TOO MANY DATA WORDS
GETLI2:	MOVEM T1,LINDAT(P2)	;SAVE EVEN CHKSUM
	ADD T1,CHKSUM		;ADD CHKSUM INTO T1
	TRNE T1,177777		;CHECKSUM SHOULD BE 0
	JRST ERR15		;CHECKSUM ERROR
	LDB T1,[POINT 16,LINWC,35] ;WC IN T1
	LDB T2,[POINT 16,LINWC,19] ;LOAD ADDR. IN T2
	RET			;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:	ILDB T2,P1		;GET NEXT CHAR.
	CAIN T2,","		;SKIP IF NOT COMMA
	RETSKP		;GOT THE DATA WORD
				;SKIP RETURN
	CAIN T2,15		;SKIP IF NOT CR
	RET			;RETURN, GOT LAST DATA WORD IN LINE
	LSH T1,6		;MAKE ROOM
	CAIE T2," "		;SKIP IF BLANK
	DPB T2,[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
	CALL WTRGX		;SET PC
	MOVEI T3,DXDR0		;SELCT IR
	CALL 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)
	CALL 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
	CALL 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
	CALL WTRGX		;STOP MICROPROCESSOR
	PREWT (DXDR1)		;CLR PC
	TRO T2,PC.EN+MS.EN	; AND SET BITS
	CALL WTRGX		;DO IT
	PREWT (DXDR0)		;LOAD IR WITH INSTR.
	MOVE T2,T1		; AND LOAD IT IN LOC. 0, ALSO
	CALL WTRGX		;
	PREWT (DXDR1)		;SELCT PC REG.
	TRO T2,IR.EN+PC.AI		;SET IR.EN & PC.AI BIT
	CALL WTRGX		;PC HAS 0
	PREWT (DXMTR)		;READY TO EXECUTE
	TRO T2,MP.SC+MP.STA	;SET SINGLE STEP & START BITS
	CALL 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
	RETSKP			;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:	STOR T3,DO.RS		;SET RS FIELD BIT 0-5 IN T2
	TXO 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
	TXNE T1,CI.RAE		;WAS RAE ERROR?
	JRST WTREG2		;YES, JUMP
	POP P,T1		;RESTORE T1
	RET			;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
	HRROI T1,[ASCIZ/  RAE Error on Write
		/]		;GET ERROR MESSAGE
	PSOUT			;PUT IT OUT
	  ERJMP JERR1		;JSYS ERROR
	POP P,T1		;RESTORE T1
	RET			;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
	STOR 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
	TXNE 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)
	JRST RDREG3		;ERROR, JUMP
RDEXIT:	ANDI T1,177777		;CLEAR OUT GARBAGE
	RET			;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
	TXNE F,DR.CHK		;IS CHECKING FOR DRIVE?
	JRST RDRG2A		;NO, JUMP
	HRROI T1,[ASCIZ/  RAE Error on Read
/]				;GET ERROR MESSAGE
	PSOUT			;PUT IT OUT
	  ERJMP	JERR1		;JSYS ERROR
RDRG2A:	POP P,T1		;RESTORE RESULT
	JRST RDEXIT		;RETURN
	
RDREG3:	PUSH P, T1		;SAVE RESULT AGAIN
	HRROI T1,[ASCIZ/  CPE or TRA Error on Read
/]				;GET ERROR MESSAGE
	PSOUT			;PUT IT OUT
	  ERJMP JERR1		;JSYS ERROR
	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 THE RIGHT DX20.
;THE DX20 MUST BE THE TAPE OR DISK VERSION DEPENDING ON THE VALUE
;OF THE FLAGS F.DISK AND F.TAPE.  IF NEITHER IS SPECIFIED, THEN EITHER
;KIND OF DX20 IS LEGAL.  OTHERWISE, WE ONLY ALLOW THE SPECIFIED TYPE.
; T4/ DRIVE NUMBER
;
;	CALL CHKDRV
;
; RETURN+1: FAIL RETURN, NOT DX20
; RETURN+2: SUCCESS RETURN


CHKDRV:	MOVEI T3,DXDTR		;GET REGISTER NUMBER
	TXO F,DR.CHK		;MARK CHECKING FOR DRIVE
	CALL RDREG		;READ DRIVE TYPE REGISTER
	TXZ F,DR.CHK		;RESET THE MARK FLAG
	LOAD T2,DT.TYP		;GET TYPE IN T2
	TXNE F,F.DISK		;DOES IT HAVE TO BE A DISK DX20?
	JRST CHKDR2		;YES, GO CHECK THAT IT IS
	TXNN F,F.TAPE		;DOES IT HAVE TO BE A TAPE DX20?
	JRST CHKDR3		;NO, GO ON
	CAIN T2,TY.DXA		;YES, IS THIS A TAPE DX20?
	RETSKP			;YES, OK
	RET			;NO

CHKDR3:	CAIE T2,TY.DXA		;CAN BE EITHER, SO IS IT TAPE?
CHKDR2:	CAIN T2,TY.DXB		;OR DISK?
	RETSKP			;YES, OK THEN
	RET			;NO, FAIL




;SUBROUTINE TO DEFAULT DX20 TYPE IF POSSIBLE.  IF NEITHER /R NOR /T WAS
;SPECIFIED, AND THE FILENAME BEING LOADED IS THE PROPER NAME, WE
;ASSUME TAPE OR DISK.
;RETURNS:
;  +1:	ALWAYS, WITH F.TAPE OR F.DISK POSSIBLY SET



DEFTYP:	TXNN F,F.TAPE!F.DISK	;ALREADY SPECIFIED DISK OR TAPE?
	SKIPN T2,JFN		;OR NO FILE WAS SPECIFIED?
R:	RET			;YES, DO NOTHING
	HRROI T1,TSTNAM		;POINT TO BUFFER
	MOVX T3,<FLD(.JSAOF,JS%NAM)>	;WANT NAME ONLY
	JFNS			;STORE IT
	 ERJMP R		;FAILED, RETURN
	MOVE T1,TSTNAM		;GET FIRST FIVE CHARACTERS
	CAMN T1,[ASCII/DXMCA/]	;FILE START WITH STANDARD TAPE FILENAME?
	TXO F,F.TAPE		;YES, SET THAT WE WANT TAPE DX20
	CAMN T1,[ASCII/DXMCE/]	;FILE START WITH STANDARD DISK NAME?
	TXO F,F.DISK		;YES, SET THAT WE WANT DISK DX20
	RET			;DONE
SUBTTL ROUTINES TO PRINT RHNUM AND DRVNUM

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

PRHDRV:	HRROI T1,[ASCIZ/
DX20 SELECTED:   /]		;GET CHAR. STRING
	PSOUT			;PUT IT OUT
	  ERJMP JERR1		;
	CALL PRH		;CALL ROUTINE TO PRINT RHNUM
	CALL PDRV		;CALL ROUTINE TO PRINT DRVNUM
	HRROI T1,[ASCIZ/
/]				;PUT CRLF
	PSOUT			;OUTPUT IT
	  ERJMP JERR1
	RET			;RETURN

;PRH - PRINTS OUT THE OCTAL DIGIST IN RHNUM
;	CALL PRH
; RETURN+1: ALWAYS

PRH:	HRROI T1,[ASCIZ/ RH20=/]
	PSOUT			;PUT OUT HEADING
	  ERJMP JERR1		;JUMP IF ERROR
	MOVE T2,RHNUM		;GET C(RHNUM)
	MOVEI T1,.PRIOU		;TERMINAL AS OUTPUT DEVICE
	MOVEI T3,^D8		;RADIX 8
	NOUT			;OUTPUT IT
	  ERJMP JERR12
	RET			;GOOD RETURN

;PDRV - PRINTS OUT THE OCTAL DIGIT IN DRVNUM
;	CALL PDRV
; RETURN+1: ALWAYS

PDRV:	HRROI T1,[ASCIZ/  DX20=/] ;GET CHAR.STRING
	PSOUT			;OUTPUT IT
	  ERJMP JERR1
	MOVE T2,DRVNUM		;GET C(DRVNUM)
	MOVEI T1,.PRIOU		;TERMINAL AS  OUTPUT DEVICE
	MOVEI T3,^D8		;RADIX 8
	NOUT			;PUTOUT THE NUMBER
	  ERJMP JERR12		;JSYS ERROR
	RET			;GOOD RETURN
	SUBTTL ERROR ROUTINES FOR COMMAND INPUT MODULE

;ERROR IN JSYS CALL

JERR:	JSERR			;TYPE MSG ON TERMINAL
	JRST BEGIN		;START ALL OVER AGAIN

;CX IS USED TO TELL WHERE AN ERROR OCCURRED IN JSYS CALL

JERR0:	MOVEI CX,0		;
	JRST JERR

JERR1:	MOVEI CX,1		;
	JRST JERR

JERR2:	MOVEI CX,2		;
	JRST JERR

JERR3:	MOVEI CX,3		;
	JRST JERR

JERR4:	MOVEI CX,4		;
	JRST JERR

JERR5:	MOVEI CX,5		;
	JRST JERR

JERR6:	MOVEI CX,6		;
	JRST JERR

JERR7:	MOVEI CX,7		;
	JRST JERR

JERR8:	MOVEI CX,^D8		;
	JRST JERR

JERR9:	MOVEI CX,^D9		;
	JRST JERR

JERR10:	MOVEI CX,^D10		;
	JRST JERR

JERR11:	MOVEI CX,^D11		;
	JRST JERR

JERR12:	MOVEI CX,^D12
	JRST JERR

JERR13:	MOVEI CX,13		;
	JRST JERR

;ROUTINES FOR NON JSYS ERROR

ERR1:	MOVEI CX,1		;
	JRST ERR

ERR2:	MOVEI CX,2		;
	JRST ERR

ERR3:	MOVEI CX,3		;
	JRST ERR

ERR4:	MOVEI CX,4		;
	JRST ERR

ERR5:	MOVEI CX,5		;
	JRST ERR

ERR6:	MOVEI CX,6		;
	JRST ERR

ERR7:	MOVEI CX,7		;
	JRST ERR

ERR8:	MOVEI CX,^D8
	JRST ERR

ERR9:	MOVEI CX,^D9		;
	JRST ERR

ERR10:	MOVEI CX,^D10		;
	JRST ERR
 
ERR11:	MOVEI CX,^D11		;
	JRST ERR

ERR12:	MOVEI CX,^D12			;
	JRST ERR

ERR13:	MOVEI CX,^D13		;
	JRST ERR

ERR14:	MOVEI CX,^D14		;
	JRST ERR

ERR15:	MOVEI CX,^D15		;
	JRST ERR

ERR16:	MOVEI CX,^D16		;
	JRST ERR

ERR17:	MOVEI CX,^D17		;
	JRST ERR

ERR18:	MOVEI CX,^D18		;
	JRST ERR
 
ERR19:	MOVEI CX,^D19		;
	JRST ERR

ERR20:	MOVEI CX,^D20		;
	JRST ERR
 
ERR21:	MOVEI CX,^D21		;
	JRST ERR

ERR22:	MOVEI CX,^D22		;
	JRST ERR

ERR23:	MOVEI CX,^D23		;
	JRST ERR
ERR:	HRROI T1,@MSGTB-1(CX)	;PTR TO ERR. MSG. IN T1
	PSOUT			;PRINT MSG
	  ERJMP JERR1
	CALL CRLF		;GIVE A CRLF
	JRST BEGIN		;START ALL OVER AGAIN

;TABLE CONTAIN ASCIZ STRING FOR ERROR MESSAGES
; USE XX TO DEFINE TABLE ENTRY

	DEFINE XX(A),<
	[ASCIZ \?'A\]>		;;END OF XX

MSGTB:	XX	Backup limit for editing reached
	XX	Command string too long
	XX	Invalid switch (2nd character must be space or colon)
	XX	Illegal switch
	XX	</D switch requires an octal number>
	XX	Colon illegal for switch
	XX	</S switch error>
	XX	Unused
	XX	Unused
	XX	1st Character wrong in dataline
	XX	2nd character wrong in dataline
	XX	Format error in dataline
	XX	Format error in dataline
	XX	Too many words in dataline
	XX	Checksum error in dataline
	XX	DX20 starting address unmatched
	XX	Specified RH20 does not exist
	XX	Specified device is not a DX20
	XX	More than one DX20 found - use /D switch
	XX	No DX20 of the proper kind was found
	XX	CRAM parity error during verification
	XX	</V or /L switch with no file name specified>
	XX	<Illegal to specify both /T and /R>
	MTBSZ==.-MSGTB
	SUBTTL STORAGE ALLOCATION 

STAK:	BLOCK PDLTH		;STACK FOR ROUTINE CALLS
CMDBUF:	BLOCK BUFLEN		;COMMAND INPUT BUFFER
JFN:	Z			;JFN FOR THE FILE
FILNAM:	BLOCK BUFLEN		;FILE NAME FOR LOADING
TSTNAM:	BLOCK 20		;NAME FOR CHECKING
JFNBLK:	Z			;.GJGEN
	XWD .NULIO,.NULIO	;.GJSRC
	Z			;.GJDEV
	Z			;.GJDIR
	Z			;.GJNAM
	Z			;.GJEXT
	Z			;.GJPRO
	Z			;.GJACT
	Z			;.GJJFN
DEFEXT:	ASCIZ \ADX\		;DEFAULT FILE TYPE FOR DX20 MICROCODE
STALOC:	Z			;STARTING ADDR. FOR MICRO-CODE
PROMPT:	ASCIZ /
File: /				;PROMPT MSG
VERFLC:	Z			;NUMBER OF CRAM VERIFICATION FAILURES
VERFLW:	Z			;NUMBER OF WORKING MEMORY VERIFICATION FAILURES
RH2CNI:	Z			;STORE IOT'S
RH2CNO:	Z
RH2DTI:	Z
RH2DTO:	Z
XRHNUM:	Z			;SAVE THE RH20 NUMBER HAS THE DX20
XRHCNI:	Z			;IO INSTR. FOR THE RH20 HAS THE DX20
XRHCNO:	Z
XRHDTI:	Z
XRHDTO:	Z
LINWC:	Z			;LOAD ADDR,,WORD COUNT OF DATA LINE
LINDAT:	BLOCK ^D32		;SO MANY DATA WORDS
CHKSUM:	Z			;CHECKSUM FOR DATALINE FROM FILE
DATLIN:	BLOCK ^D32		;DATA LINE FROM FILE
	END BEGIN