Google
 

Trailing-Edge - PDP-10 Archives - BB-H138A-BM - 3a-sources/dx20ld.mac
There are 17 other files named dx20ld.mac in the archive. Click here to see a list.
;<FORTMILLER>DX20LD.MAC.20, 12-Jul-78 16:06:43, Edit by FORTMILLER
;Change some error messages
;<FORTMILLER>DX20LD.MAC.19,  11-Jul-78 16:58:01, Edit by FORTMILLER
;Fix bug which rejected lower case switches
;Don't exit to monitor after completion of a command
;<3A.DX20-MICROCODE>DX20LD.MAC.18,  2-Jun-78 17:05:51, Edit by FORTMILLER
;<3A.DX20-MICROCODE>DX20LD.MAC.17,  2-Jun-78 17:03:18, Edit by FORTMILLER
;<FORTMILLER>DX20LD.MAC.16,  1-Jun-78 20:58:01, Edit by FORTMILLER
;<FORTMILLER>DX20LD.MAC.15, 31-May-78 19:56:59, Edit by FORTMILLER
;INSERT COPYRIGHT
;<FORTMILLER>DX20LD.MAC.14, 31-May-78 19:49:50, Edit by FORTMILLER
;ADD CODE TO PUT THE MAGIC VALUE (42562) INTO LOC 11 AS PER
; DX20 MICROCODE SPEC 105-220-001-00
;<FORTMILLER>DX20LD.MAC.13,  9-May-78 10:29:20, Edit by FORTMILLER
;<FORTMILLER>DX20LD.MAC.12, 11-Apr-78 16:01:03, Edit by FORTMILLER
;<FORTMILLER>DX20LD.MAC.9, 11-Apr-78 14:41:59, Edit by FORTMILLER
;<FORTMILLER>DX20LD.MAC.7, 11-Apr-78 14:07:06, Edit by FORTMILLER
;<FORTMILLER>DX20LD.MAC.6, 11-Apr-78 14:05:18, Edit by FORTMILLER
;<FORTMILLER>DX20LD.MAC.4, 10-Apr-78 15:16:47, Edit by FORTMILLER
;<OUYANG>BTLOD.MAC.31, 26-May-77 12:26:57, Edit by OUYANG
;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 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. 1,1,4,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)

;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.DX2==60			;DX20 DRIVE TYPE***(=050060)
				; VERSION # IS 100****(100017)

;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
	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
	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)
	RET			;NO, ILLEGAL SWITCH
	HALTF			;/E EXIT RIGHT NOW
	JRST BEGIN		;IF CONTINUE, RESTART

;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:	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 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
	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:	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
	JRST ERR8		;ERROR, NOT MATCH
	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 VRFDX		;BACK FOR NEXT LINE
;VERIFY WORKING MEMEORY AGAIN WM LOAD LINE
VRFWM:	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
	CAME T2,T1		;VERIFY WM WORD
	 JRST ERR9		;ERROR, NOT MATCH
	AOBJN Q1,VRFWM2		;GET READY FOR NEXT WM WORD
	CALL POSWM		;RESTORE LOC 0 OF CRAM
	  JRST VRFDX		;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
	HRROI T1,[ASCIZ/	Microcode Verified
/]
	PSOUT			;OUTPUT MESSAGE
	  ERJMP JERR1
	RET			;RETURN
;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