Trailing-Edge
-
PDP-10 Archives
-
tops10_703_distr_bb-x140b-sb
-
10,7/703mon/dx2com.mac
There are 2 other files named dx2com.mac in the archive. Click here to see a list.
TITLE DX2COM -- COMMON CODE FOR ALL DEVICES DRIVEN THROUGH DX20'S V012
SUBTTL G.M. UHLER/GMU 10 SEP 85
SEARCH F,S,ICHPRM
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
.CPYRT<1981,1986>
;COPYRIGHT (C) 1981,1984,1986
;BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
;ALL RIGHTS RESERVED.
;
XP VDX2CM,012
SALL
;ASSEMBLY INSTRUCTIONS:
; .R MACRO
; *DX2COM,DX2COM/C=DX2COM
DX2COM::ENTRY DX2COM
;TECHNICAL INFORMATION AND TECHNIQUES FOR PROGRAMMING THE
;RH20/DX20 ARE AVAILABLE IN THE FOLLOWING DOCUMENTS:
;
; DX20 PROGRAMMED DEVICE ADAPTER TECHNICAL MANUAL,
; DOCUMENT NUMBER EK-0DX20-TM-001, FEB 78
; RH20 MASSBUS CONTROLLER UNIT DESCRIPTION,
; DOCUMENT NUMBER EK-RH20-UD-001, AUG 76
SUBTTL MACRO DEFINITIONS
;MACRO TO COMPUTE THE WIDTH OF A MASK
; "WID" RETURNS THE LENGTH OF THE LEFTMOST STRING OF
; CONSECUTIVE ONES IN THE WORD.
DEFINE WID(MASK),<<^L<-<<MASK>_<^L<MASK>>>-1>>>
;MACRO TO COMPUTE THE POSITION OF A MASK
DEFINE POS(MASK),<<^L<MASK>+^L<-<<MASK>_<^L<MASK>>>-1>-1>>
;MACRO TO BUILD A POINTER TO A MASKED QUANTITY
; POINTR LOCATION,MASK
DEFINE POINTR(LOC,MASK),<<POINT WID(MASK),LOC,POS(MASK)>>
;MACRO TO INSERT A VALUE IN A MASKED FIELD
; INSVL.(VALUE,MASK)
DEFINE INSVL.(VALUE,MASK),<<<<VALUE>B<POS(<MASK>)>>&<MASK>>>
;MACRO TO WAIT AWHILE. USED IN RDREG TO GIVE THE MASSBUS TIME TO
;ACCEPT THE DATAO TO SETUP THE PREPARATION REGISTER BEFORE
;DOING THE DATAI TO READ THE REGISTER
DEFINE STALL, <
IMULI P,1
XLIST
IMULI P,1
LIST
>
SUBTTL DX20 DEVICE DEPENDENT REGISTER/BIT DEFINITIONS
.DXMTR==03B5 ;MAINTENANCE REGISTER
MR.SCY==1B31 ;MICROPROCESSOR SINGLE CYCLE
MR.STR==1B33 ;MICROPROCESSOR START
MR.RES==1B34 ;MICROPROCESSOR RESET
.DXDTR==06B5 ;DRIVE TYPE REGISTER
.DXMIR==30B5 ;MICROCONTROLLER INSTRUCTION REGISTER
.DXPCR==31B5 ;MICROPROCESSOR PC REGISTER
PC.IRE==1B20 ;INSTRUCTION REGISTER ENABLE
PC.MSE==1B21 ;MICROSTORE ENABLE
PC.PCE==1B22 ;PC ENABLE
PC.PCI==1B23 ;PC AUTO INCREMENT
PC.MPC==7777B35 ;MICROPROCESSOR PC
.DXIBR==36B5 ;DIAGNOSTIC REGISTER 7
DX.IBR==377 ;CONTENTS OF THE BR REGISTER
.DXIPE==37B5 ;DIAGNOSTIC REGISTER 7
DX.IPE==1B22 ;INSTRUCTION REGISTER PARITY ERROR
.CRM10==10 ;LOCATION IN THE CRAM CONTAINING A CODE
; CHECKED BY THE DRIVERS TO SEE IF THE
; MICROCODE IS VALID
.DXSAD==1 ;FULL START ADDRESS FOR ALL VERSIONS
; OF THE DX20 MICROCODE
SUBTTL DX20 MICROCODE LOADING SUBROUTINES
;ROUTINE TO CLEAR, LOAD, AND VERIFY, AND START THE MICROCODE FOR A DX20.
;CALL:
; T1/ADDRESS OF MICROCODE LOADER BLOCK
; PUSHJ P,DXLOAD
;RETURN CPOPJ IF UNSUCCESSFUL
; CPOPJ1 WITH MICROCODE LOADED BUT NOT STARTED
DXLOAD::PUSHJ P,SAVE4## ;SAVE SOME ACS
MOVE P1,T1 ;COPY MICROCODE LOADER BLOCK ADDRESS
PUSHJ P,BTUCOD## ;FIND ADDRESS
JRST DXLOA1 ;NOT AVAILABLE
PUSHJ P,MPRES ;RESET THE MICROPROCESSOR
PUSHJ P,DXCLR ;CLEAR THE CRAM AND WORKING MEMORY
PUSHJ P,LOAD ;LOAD THE MICROCODE
JRST DXLOA1 ;FAILED
PUSHJ P,VERIFY ;VERIFY THE MICROCODE THAT WE JUST LOADED
JRST DXLOA1 ;FAILED
PUSHJ P,MPCHK ;DO A FINAL CHECK ON THE MICROSTORE
JRST DXLOA1 ;FAILED
PUSHJ P,RDCRM0 ;READ THE VERSION NUMBER FROM CRAM LOC 0
LDB T1,[POINT 6,T2,25] ;GET MAJOR VERSION
LSH T1,30 ;POSITION
TRZ T2,777600 ;ISOLATE EDIT LEVEL
IOR T2,T1 ;FORM STANDARD DEC-10 VERSION NUMBER
PUSH P,T2 ;SAVE IT
PUSHJ P,DXSTRT ;START THE DX20
POP P,.ULVER(P1) ;SET VERSION IN MICROCODE LOADER BLOCK
MOVE T1,P1 ;POINT TO THE MICROCODE LOADER BLOCK ADDRESS
PUSHJ P,BTURPT## ;REPORT A SUCESSFUL LOAD
JRST CPOPJ1## ;GIVE SKIP RETURN
DXLOA1: MOVEI T2,.CRM10 ;WRITE A 0 INTO CRAM LOCATION 10
MOVEI T3,0 ; SO THAT ATTEMPTS TO START THIS DX20
PUSHJ P,WRCRAM ; WILL FAIL
MOVE T1,P1 ;COPY MICROCODE LOADER BLOCK ADDRESS
PJRST BTURPT## ;REPORT LOAD ERROR AND RETURN
;It might occur to someone to call BTURPT before DXSTRT to save the
;PUSH and POP of the microcode version number. It is done that way
;to waste enough KL CPU time to give the DX20 microprocessor enough
;time to get through its full initialization and get to the idle
;loop before a massbus init or a call to the reset routine stops
;it again. If the DX20 doesn't finish its initialization, the
;restart of the microprocessor (at a different start address than
;that used by DXSTRT) will cause strange things to happen.
;ROUTINE TO LOAD OR VERIFY THE MICROCODE IN A DX20.
;CALL:
; P1/ADDRESS OF MICROCODE LOADER BLOCK
; PUSHJ P,LOAD/VERIFY
;RETURN CPOPJ IF ERROR
; CPOPJ1 WITH FUNCTION PERFORMED SUCCESSFULLY
LOAD: PUSH P,[.DXPCR!PC.MSE!PC.PCE] ;DATAO BITS TO WRITE CRAM
PUSH P,[IFIW LDCRAM] ;ROUTINE TO LOAD CRAM
PUSH P,[IFIW LDWM] ;ROUTINE TO LOAD DRAM
PUSH P,[.UEDRL,,.UECRL] ;DRAM,,CRAM ERROR CODES
JRST FUNC ;ENTER COMMON CODE
VERIFY: PUSH P,[.DXPCR!PC.IRE!PC.PCE] ;DATAO BITS TO READ CRAM
PUSH P,[IFIW VFCRAM] ;ROUTINE TO VERIFY CRAM
PUSH P,[IFIW VFWM] ;ROUTINE TO VERIFY DRAM
PUSH P,[.UEDRV,,.UECRV] ;DRAM,,CRAM ERROR CODES
FUNC: PUSH P,[EXP 0] ;RESERVE SPACE FOR CRAM LOCATION 0
MOVSI P2,-3777 ;AOBJN POINTER
MOVSI P3,(<POINT 18,,>!1B12) ;MAKE A TWO WORD BYTE POINTER
MOVE P4,.ULADR(P1) ;GET UCODE ADDRESS
FUNC1: ILDB T1,P3 ;GET A BYTE OF DATA
HRRZ T2,P2 ;GET CRAM ADDRESS
SKIPE T3,.ULMAG(P1) ;HAVE A MAGIC NUMBER TRANSLATION TABLE?
PUSHJ P,MAGIC ;YES--SEE IF A SUBSTITUTION IS NECESSARY
IOR T2,-4(P) ;INCLUDE DATAO BITS TO READ/WRITE CRAM
PUSHJ P,WTREG ;INITIALIZE ADDRESS OF CRAM LOCATIONS
PUSHJ P,@-3(P) ;DISPATCH TO CRAM FUNCTION ROUTINE
JRST FUNC3 ;ERROR
AOBJN P2,FUNC1 ;LOOP
PUSHJ P,RDCRM0 ;READ THE CONTENTS OF CRAM LOCATION 0
HRRZM T2,(P) ;SAVE ON STACK
MOVSI P2,-1777 ;AOBJN POINTER
MOVSI P3,(<POINT 8,,>!1B12) ;MAKE A TWO WORD BYTE POINTER
MOVE P4,.ULADR(P1) ;GET ADDRESS OF UCODE STORAGE
ADDI P4,2000 ;OFFSET TO THE DRAM DATA
FUNC2: HRRZ T2,P2 ;GET WORKING MEMORY ADDRESS
PUSHJ P,LDMAR ;SET MAR/MARX TO THAT VALUE
ILDB T1,P3 ;GET A BYTE OF DATA
ANDI T1,377 ;KEEP ONLY 8 BITS
PUSHJ P,@-2(P) ;DISPATCH TO WORKING MEMORY FUNCTION ROUTINE
JRST FUNC4 ;ERROR
AOBJN P2,FUNC2 ;LOOP
MOVEI T2,0 ;RESTORE THE VALUE THAT WAS IN CRAM LOCATION
POP P,T3 ;GET PREVIOUS CONTENTS OF CRAM LOCATION 0
PUSHJ P,WRCRAM ; LOADING WORKING MEMORY
ADJSP P,-4 ;PHASE STACK
JRST CPOPJ1## ;RETURN
FUNC3: SKIPA T1,-1(P) ;CRAM LOAD/VERIFY ERROR
FUNC4: HLRZ T1,-1(P) ;DRAM LOAD/VERIFY ERROR
DPB T1,ULBEBP## ;STORE
ADJSP P,-5 ;PHASE STACK
POPJ P, ;RETURN
;ROUTINE TO CLEAR THE CRAM AND WORKING MEMORY OF A DX20.
;CALL:
; P1/ADDRESS OF MICROCODE LOADER BLOCK
; PUSHJ P,DXCLR
;RETURN CPOPJ ALWAYS
DXCLR: PUSH P,F ;SAVE F
MOVSI F,-4000 ;4000 LOCATIONS TO CLEAR IN THE CRAM
DXCLR1: HRRZ T2,F ;GET THE ADDRESS TO WRITE
MOVEI T3,0 ;PUT A ZERO IN IT
PUSHJ P,WRCRAM ;WRITE THE CRAM LOCATION
AOBJN F,DXCLR1 ;WRITE THEM ALL
MOVEI T2,0 ;SET THE MAR/MAR EXTENSION
PUSHJ P,LDMAR ; TO 0
MOVEI F,2000 ;2000 LOCATIONS IN THE WORKING MEMORY
DXCLR2: MOVEI T2,11400 ;LDMEM 0,I MICROINSTRUCTION
PUSHJ P,DXXCT ;CLEAR NEXT LOCATION IN WORKING MEMORY
SOJG F,DXCLR2 ;DO THEM ALL
JRST FPOPJ## ;RESTORE F AND RETURN
;ROUTINE TO START THE DX20 MICROPROCESSOR AT THE FULL START ENTRY
;POINT.
;CALL:
; P1/ADDRESS OF MICROCODE LOADER BLOCK
; PUSHJ P,DXSTRT
;RETURN CPOPJ ALWAYS
DXSTRT: PUSHJ P,MPRES ;MAKE SURE THE PROCESSOR IS RESET
MOVE T2,[.DXPCR!PC.IRE!PC.PCE!PC.PCI!INSVL.(.DXSAD,PC.MPC)]
PUSHJ P,WTREG ;SET THE PC TO THE FULL START ADDRESS
MOVE T2,[.DXMTR!MR.STR] ;MAINTENANCE REGISTER+START BIT
PJRST WTREG ;START THE MICROPROCESSOR AND RETURN
;ROUTINE TO READ THE CONTENTS OF CRAM LOCATION 0.
;CALL:
; P1/ADDRESS OF MICROCODE LOADER BLOCK
; PUSHJ P,RDCRM0
;RETURN CPOPJ ALWAYS WITH:
; T2/CONTENTS OF CRAM LOCATION 0
RDCRM0: MOVE T2,[.DXPCR!PC.IRE!PC.PCE!INSVL.(0,PC.MPC)] ;SET TO READ
PUSHJ P,WTREG ; CRAM LOCATION 0
MOVSI T2,(.DXMIR) ;READING THIS REGISTER RETURNS THE VALUE
PJRST RDREG ; THAT IS ADDRESSED BY THE PC REGISTER
;ROUTINE TO WRITE A WORD INTO A DX20 CRAM LOCATION.
;CALL:
; T2/ADDRESS OF LOCATION TO WRITE
; T3/DATA TO BE WRITTEN
; P1/ADDRESS OF MICROCODE LOADER BLOCK
; PUSHJ P,WRCRAM
;RETURN CPOPJ ALWAYS
WRCRAM: PUSH P,T3 ;SAVE THE DATA TO BE WRITTEN
TDO T2,[.DXPCR!PC.MSE!PC.PCE] ;PC REGISTER+BITS TO ENABLE
PUSHJ P,WTREG ; MICROSTORE AND PC WRITES
POP P,T2 ;RESTORE THE DATA TO BE WRITTEN
HRLI T2,(.DXMIR) ;WRITES INTO THE IR GO INTO THE CRAM LOCATION
PJRST WTREG ; ADDRESSED BY THE PC REGISTER
;ROUTINE TO LOAD THE DX20 MEMORY ADDRESS AND ADDRESS EXTENSION REGISTERS
;(MAR AND MARX) WITH A VALUE.
;CALL:
; T2/ADDRESS TO LOAD
; P1/ADDRESS OF MICROCODE LOADER BLOCK
; PUSHJ P,LDMAR
;RETURN CPOPJ ALWAYS
LDMAR: PUSH P,T2 ;SAVE THE ADDRESS TO LOAD
ANDI T2,377 ;KEEP LOW 8 BITS
TRO T2,1000 ;ADD A LDMAR MICROINSTRUCTION
PUSHJ P,DXXCT ;EXECUTE IT
POP P,T2 ;RESTORE THE ADDRESS TO LOAD
LSH T2,-^D8 ;GET 2 HIGH ORDER BITS
TRO T2,400 ;ADD A LDMARX MICROINSTRUCTION
PJRST DXXCT ;EXECUTE THAT AND RETURN
;ROUTINE TO CAUSE THE DX20 TO EXECUTE AN INSTRUCTION.
;CALL:
; T2/MICROINSTRUCTION TO EXECUTE
; P1/ADDRESS OF MICROCODE LOADER BLOCK
; PUSHJ P,DXXCT
;RETURN CPOPJ ALWAYS
DXXCT: PUSH P,T2 ;SAVE THE INSTRUCTION TO EXECUTE
MOVE T2,[.DXMTR!MR.SCY] ;GET MAINTENANCE REGISTER AND SINGLE CYLCLE
PUSHJ P,WTREG ;FORCE THE DX20 INTO SINGLE CYCLE MODE
MOVEI T2,0 ;STORE THE INSTRUCTIN TO EXECTUTE IN CRAM LOC 0
POP P,T3 ;RESTORE THE INSTRUCTION TO EXECUTE
PUSHJ P,WRCRAM ;WRITE IT INTO THE CRAM
MOVE T2,[.DXPCR!PC.IRE!PC.PCI] ;PC REG+IR ENABLE+PC AUTO INCR
PUSHJ P,WTREG ;SETUP TO EXECUTE THE INSTRUCTION
MOVE T2,[.DXMTR!MR.SCY!MR.STR] ;MAINT REG+SINGLE CYCLE+START
PUSHJ P,WTREG ;EXECUTE THE INSTRUCTION
MOVSI T2,(.DXMTR) ;CLEAR SINGLE CYCLE AND LEAVE START OFF
PJRST WTREG ;CLEAR START AND RETURN
;ROUTINE TO LOAD DATA INTO A CRAM LOCATION.
;CALL:
; T1/16 BITS OF DATA TO WRITE
; P1/ADDRESS OF MICROCODE LOADER BLOCK
; PUSHJ P,LDCRAM
;RETURN CPOPJ1 ALWAYS
LDCRAM: HRRZ T2,T1 ;MOVE DATA TO THE RIGHT AC
HRLI T2,(.DXMIR) ;ADD THE REGISTER THAT WE WANT
PUSHJ P,WTREG ;DO THE DATAO THAT CAUSES THE WRITE
JRST CPOPJ1## ;GIVE SKIP RETURN
;ROUTINE TO LOAD DATA INTO A WORKING MEMORY LOCATION.
;CALL:
; T1/8 BITS OF DATA TO WRITE
; P1/ADDRESS OF MICROCODE LOADER BLOCK
; PUSHJ P,LDWM
;RETURN CPOPJ1 ALWAYS
LDWM: HRRZ T2,T1 ;GET DATA INTO THE WRITE AC
TRO T2,11400 ;ADD A LDMEM N,I MICROINSTRUCTION
PUSHJ P,DXXCT ;EXECUTE THE INSTRUCTION
JRST CPOPJ1## ;GIVE SKIP RETURN
;ROUTINE TO VERIFY THE DATA IN A CRAM LOCATION.
;CALL:
; T1/16 BITS OF CRAM DATA
; P1/ADDRESS OF MICROCODE LOADER BLOCK
; PUSHJ P,VFCRAM
;RETURN CPOPJ IF NO MATCH
; CPOPJ1 IF MATCH
VFCRAM: MOVSI T2,(.DXMIR) ;READ THIS REGISTER TO GET THE DATA
PUSHJ P,RDREG ;READ THE DATA
CAIN T2,(T1) ;MATCH WITH WHAT IT SHOULD BE?
AOS (P) ;YES--SKIP
POPJ P, ;RETURN
;ROUTINE TO VERIFY THE DATA IN A WORKING MEMORY LOCATION
;CALL:
; T1/8 BITS OF DATA
; P1/ADDRESS OF MICROCODE LOADER BLOCK
; PUSHJ P,VFWM
;RETURN CPOPJ IF NO MATCH
; CPOPJ1 IF MATCH
VFWM: MOVEI T2,043411 ;GET A MOVMEM BR,I MICROINSTRUCTION
PUSHJ P,DXXCT ;EXECUTE IT
MOVSI T2,(.DXIBR) ;REGISTER TO READ THE BR
PUSHJ P,RDREG ;READ THE REGISTER
ANDI T2,DX.IBR ;KEEP ONLY THE BR OUTPUT
CAIE T2,(T1) ;MATCH?
POPJ P, ;NO
JRST CPOPJ1## ;YES, GIVE SKIP RETURN
;ROUTINE TO SUBSTITUTE A MAGIC NUMBER
;CALL:
; T2/LOAD ADDRESS
; T3/MAGIC TRANSLATION TABLE
; PUSHJ P,MAGIC
;RETURN CPOPJ ALWAYS WITH T1 CONTAINING POSSIBLY UPDATED DATA
MAGIC: MOVE T4,(T3) ;GET A WORD
AOJE T4,CPOPJ## ;RETURN IF END OF TABLE
HRRZ T4,(T3) ;GET AN ADDRESS
CAIE T4,(T2) ;MATCH?
AOJA T3,MAGIC ;LOOP
HLRZ T1,(T3) ;GET ASSOCIATED MAGIC VALUE
POPJ P, ;AND RETURN
;ROUTINE TO RESET THE DX20 MICROPROCESSOR
;CALL:
; P1/ MICROCODE LOADER BLOCK ADDRESS
; PUSHJ P,MPRES
;RETURN CPOPJ ALWAYS
MPRES: MOVE T2,[.DXMTR!MR.RES] ;SET RESET BIT IN MAINT REG
PJRST WTREG ;RESET THE DX20
;ROUTINE TO CHECK THE STATUS OF THE MICROPROCESSOR
;CALL:
; P1/ADDRESS OF MICROCODE LOADER BLOCK
;RETURNS CPOPJ IF CONSISTANCY CHECKS FAIL OR CPOPJ1 IF OK
MPCHK: MOVE T2,[.DXPCR!PC.IRE!PC.PCE!PC.PCI!7] ;REGISTER TO WRITE+
; IR ENABLE+PC ENABLE+PC AUTO INCR+PC TO READ
PUSHJ P,WTREG ;WRITE THE REGISTER
MOVSI T2,(.DXMIR) ;POINT AT DIAGNOSTIC REGISTER 0
PUSHJ P,RDREG ;READ THE CONTENTS
PUSH P,T2 ;SAVE FOR COMPARE
MOVSI T2,(.DXDTR) ;POINT AT DRIVE TYPE REGISTER
PUSHJ P,RDREG ;READ THAT
POP P,T3 ;RESTORE CRAM LOCATION 7
CAME T2,T3 ;HAVE TO BE THE SAME
POPJ P, ;ERROR IF NOT
MOVSI T2,(.DXIPE) ;POINT AT DIAGNOSTIC REGISTER 7
PUSHJ P,RDREG ;READ IT
TRNN T2,DX.IPE ;IR PARITY ERROR ON LAST READ?
AOS (P) ;NO, GIVE SKIP RETURN
POPJ P, ; AND RETURN
;ROUTINE TO READ A DRIVE OR CONTROLLER REGISTER.
;CALL:
; T2/DATAO ARGUMENT TO LOAD PREPARATION REGISTER
; W/KDB ADDRESS
; PUSHJ P,RDREG
;RETURN CPOPJ ALWAYS WITH:
; T2/16 BITS OF RETURNED DATAI
;DESTROYS T3
RDREG: HRRZ T3,.ULDEV(P1) ;GET DX20 NUMBER FOR DS
TLO T2,<(DO.DRE)>(T3) ;SET DS AND DISABLE RAE
XCT .ULDTO(P1) ;TELL MBC WHICH REGISTER WE WANT TO READ
PUSH P,T2 ;SAVE THE ARGUMENT
STALL ;WAIT FOR THINGS TO SETTLE
XCT .ULDTI(P1) ;READ THE VALUE
MOVE T3,T2 ;SAVE RESULT
XCT .ULCNI(P1) ;CONI
EXCH T2,T3 ;SWAP
TRNE T3,CI.RAE ;REGISTER ACCESS ERROR?
JRST RDREG2 ;YES, TRY TO RECOVER
RDREG1: POP P,(P) ;BRING STACK INTO PHASE
ANDI T2,177777 ;RETURN ONLY DATA BITS
POPJ P, ;RETURN
RDREG2: PUSH P,T4 ;SAVE T4
MOVEI T3,^D10 ;RETRY OPERATION 10 TIMES
RDREG3: MOVEI T2,CO.MBE!CO.RAE ;MASSBUS ENABLE PLUS CLEAR RAE
XCT .ULCNO(P1) ;CLEAR THE ERROR
MOVE T2,-1(P) ;GET DATAO ARGUMENT BACK
XCT .ULDTO(P1) ;SETUP THE PREPARATION REGISTER AGAIN
STALL ;WAIT FOR THINGS TO SETTLE
XCT .ULDTI(P1) ;READ THE VALUE
MOVE T4,T2 ;SAVE RESULT
XCT .ULCNI(P1) ;CONI
EXCH T2,T4 ;SWAP
TRNE T4,CI.RAE ;REGISTER ACCESS ERROR?
SOJG T3,RDREG3 ;YES, LOOP
MOVEI T4,CO.MBE!CO.RAE ;MASSBUS ENABLE PLUS CLEAR RAE
EXCH T2,T4 ;SWAP
XCT .ULCNO(P1) ;MAKE SURE RAE IS CLEARED
MOVE T2,T4 ;RESTORE
POP P,T4 ;RESTORE T4
JRST RDREG1 ;RETURN TO THE CALLER
;ROUTINE TO WRITE ONE MASSBUS REGISTER.
;CALL:
; T2/DATAO ARGUMENT
; W/KDB ADDRESS
; PUSHJ P,WTREG
;RETURN CPOPJ ALWAYS
;DESTROYS T3
WTREG: HRRZ T3,.ULDEV(P1) ;GET DX20 NUMBER FOR DS
TLO T2,<(DO.LDR!DO.DRE)>(T3) ;DRIVE NUMBER, LOAD REG, DISABLE RAE
MOVE T3,T2 ;COPY ARGUMENTS
XCT .ULDTO(P1) ;DATAO
XCT .ULCNI(P1) ;CONI
TRNN T2,CI.RAE ;REGISTER ACCESS ERROR?
POPJ P, ;NO--RETURN
PUSH P,T3 ;SAVE ARGUMENTS
MOVEI T3,^D10 ;RETRY OPERATION 10 TIMES
WTREG1: MOVEI T2,CO.MBE!CO.RAE ;MASSBUS ENABLE PLUS CLEAR RAE
XCT .ULCNO(P1) ;CLEAR THE ERROR
MOVE T2,(P) ;GET ARGUMENTS BACK
XCT .ULDTO(P1) ;RETRY THE OPERATION
XCT .ULCNI(P1) ;CONI
TRNE T2,CI.RAE ;STILL HAVE AN ERROR
SOJG T3,WTREG1 ;YES, LOOP BUT NOT TOO MANY TIMES
MOVEI T2,CO.MBE!CO.RAE ;MASSBUS ENABLE PLUS CLEAR RAE
XCT .ULCNO(P1) ;INSURE THAT RAE IS CLEARED
POP P,T2 ;RESTORE T2
POPJ P, ;RETURN
SUBTTL END
DX2END::!END