.TITLE UD ; VERSION V007A ;  001 ; ; COPYRIGHT 1973 DIGITAL EQUIPMENT CORP. MAYNARD MASS. 01754 ; ; UDC-11 DRIVER ; ; ; GLOBAL DEFINITIONS ; .GLOBL UD ;UDC DRIVER .GLOBL UDDDB ;UDC DDB .GLOBL UD.CLK ;UDC MAINTENANCE REGISTER. .GLOBL UD.CSR ;UDC CSR REGISTER. .GLOBL UD.SCR ;UDC SCAN REGISTER. ; ; GLOBAL REFERENCES ; ; CONDITIONAL GLOBAL REFERENCE FOR ADU01 ; .IFDF AU.BAS ; .GLOBL SY.TO .GLOBL PI.GET ; .ENDC ; .GLOBL BEGUD ;UDC-11 INITIALIZATION CODE .GLOBL DV.A2 ;CREATE A002 MESSAGE SUBROUTINE. .GLOBL HSASI ;HIGH SPEED ACTIVATE SUBROUTINE. .GLOBL PL6 ;PRIORITY LEVEL 6 .GLOBL PI.ADR ;DDB-ADDRESS OF MUX ARRAY .GLOBL PI.DAT ;DDB-ADDRESS OF DATA ARRAY .GLOBL PI.ERR ;DDB-ADDRESS OF FINAL STATUS .GLOBL PI.FAD ;DDB-ADDRESS OF # OF POINTS .GLOBL PI.FCN ;DDB-SPECIAL FCN CODE STORE .GLOBL PI.FST ;DDB-FIRST CHANNEL NUMBER FOR SEQUENTIAL OPS. .GLOBL PI.NUM ;DDB-NUMBER OF POINTS .GLOBL PI.SPF ;DDB-SPECIAL FCN STORE .GLOBL PS ;ADDRESS OF PROCESSOR STATUS REGISTER. .GLOBL STRG ;COMMON SYSTEM ENTRY SUBROUTINE. .GLOBL SRTI ;COMMON SYSTEM EXIT. .GLOBL SY.DFL ;DDB-FLAG BYTE. .GLOBL SY.DPR ;DDB-PERMANENT DDB BIT. .GLOBL SY.DWN ;DDB-DEVICE IS DOWN FLAG (NOT READY). .GLOBL SY.RTN ;TASK# .GLOBL SY.SCB .GLOBL UDCT ;UDC TASK SLOT. ; .IFNDF AU.BAS ; .GLOBL UD.CHN ;UDC-NUMBER OF CHANNELS .GLOBL UD.NIM ;UDC-NUMBER OF INTERRUPTING MODULES. ; .ENDC ; .GLOBL UD.COS ;UDC-CHANGE OF STATE TABLE .GLOBL UD.GEN ;UDC-GENERIC CODES TABLE .GLOBL UD.IMD ;UDC-INT MODULE DATA .GLOBL UDNIM2 ;UDC-UD.NIM*2 .GLOBL UD.PRV ;UDC-PREVIOUS STATUS TABLE ; ; STANDARD REGISTER DEFINITIONS ; R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 ; ; DEVICE REGISTER DEFINITIONS ; UD.CSR=171776   ;UDC-11 CSR UD.SCR=171774   ;UDC-11 SCAN REGISTER UD.CLK=171772   ;UDC-11 MAINTENANCE REGISTER UD.MOD=171000  ;UDC-11 MODULE ADDRESSES. ; ; PROLOGUE ; ; DEFINE MISC ENTRY IF ADU01 MODULE IS PRESENT ; .IFDF AU.BAS ; UDMIS=UD.TB-UD ; .ENDC ; .IFNDF UD.MIS ; UD.MIS=0 ; .ENDC UD: .WORD 0  ;DDB POINTER .WORD 41  ;FACILITIES .BYTE 0  ;BUFFER SIZE .BYTE UD.INT-UD ;INTERRUPT ENTRY .BYTE PL6  ;PRIORITY .BYTE 0  ;OPEN ENTRY .BYTE 0  ;TRANSFER ENTRY .BYTE 0  ;CLOSE ENTRY .BYTE UD.SP-UD ;SPECIAL ENTRY .BYTE UD.MIS  ; MISC ENTRY UD.NAM: .RAD50 /UD/  ;DEVICE NAME ; ; .IFNDF AU.BAS ; UD.FMK=77 ; .ENDC ; ; INTERRUPT ENTRY ; UD.INT: JMP UD.N00  ;INTERRUPT ENTRY ; ; SPECIAL FUNCTION ENTRY ; ; LEGAL FUNCTIONS ARE: ; ; 0=16 BIT READ ; 1=16 BIT WRITE ; 2=VARIABLE FIELD READ ; 3=VARIABLE FIELD WRITE ; 4=GET INTERRUPT DATA ; 5=READ PREVIOUS STATE ; 6=ANALOG READ SEQUENTIAL ; 7=RESERVED BUT NOT USED,IE:ILLEGAL FUNCTION ; 8=ANALOG READ ; ; ADU01 MODULE SUPPORT ; ; THE ADU01 MODULE IS AN ANALOG INPUT MODULE HAVING 8 CHANNELS. ; IT HAS A GENERIC CODE OF 7. ALL ADU01 MODULES MUST ; OCCUPY CONTIGUOUS ADDRESSES IN THE UDC CONTROLLER. ; ; AU.BAS = THE FIRST MODULE NUMBER IN THE CONTIGUOUS SET. IT ;   HAS A VALUE FROM 0 TO 251 (10) WHEN SPECIFIED IN THE ;   USER.PAL FILE AT SYSTEM GENERATION ; ; AU.MAX - THE TOTAL NUMBER OF CHANNELS IN THE ADU01 SET. IT WILL ;   WILL HAVE VALUES SUCH AS 8,16,24... ; ; AU.BAS AND AU.MAX MUST BE SPECIFIED IN THE USER.PAL FILE ; FOR SYSTEM GENERATION ALONG WITH UD.CHN AND UD.NIM. ; EACH ADU01 MODULE COUNTS 1 FOR THE UD.CHN AND UD.NIM VALUES. ; .IFDF AU.BAS ; .IFNDF AU.MAX ; AU.MAX=8.  ;ASSUME 1 MODULE ; .ENDC ; .IFNDF AU.GEN ; AU.GEN=7  ;DEFAULT GENERIC CODE FOR ADU01 ; .ENDC ; UD.FMK=577 ; ; MISC ENTRY TABLE ; UD.TB: .WORD 0 ;NOT THIS .WORD AU.TMO .WORD 0,0 ; AU.TMO: MOV UD,R0  ;GET DDB ADR BNE 1$  ;BR IF OK RTS PC  ;IF UD=0,NOTHING IS HAPPENING 1$: INC AU.EFG  ;SET ERROR FOR ANALOG TIMEOUT CLR R1  ;GET A ZER0 BR AU.SND  ;...AND CALL THIS CHAN DONE ; ; ; ROUTINE TO INITIATE TRANSFER FROM ADU01 ; ; ...INITS ERROR FLAG CLEAR ; ...JUMPS INTO SUBR TO CALC NEXT CHANNEL TO CONVERT ; ...AFTER STORING A RETURN ADR SO THE THE RETURN ; ...EXECUTED BY AU.CAL WILL CAUSE IT TO RE-ENTER ; ...THE ROUTINE HIGHER SO-AS TO INITIATE THAT REQUEST ; ...AND PROCEED TO CALCULATE THE CHANNEL FOR THE NEXT ; ...TIME THROUGH. ; AU.XFR: CLR AU.EFG  ;SET TO NO ERRORS MOV #AU.DOT,-(SP) ;SET RETURN TO START FST CONVERT BR AU.CAL  ;GO CALCULATE FIRST CHAN INFO ; ; ROUTINE AU.GET---- ;THIS IS THE ROUTINE WHICH GETS COMPLETED CONVERSION DATA ;...AND PASSES IT TO THE USER BUFFER. ; AU.GET: CLR SY.TO(R0) ;TURN OFF POSSIBLE TIME OUT MOV @(PC)+,R1 ;GET CONVERTED DATA AU.NAR: .WORD 0  ;BUS ADR FOR NEXT CHAN TO READ HERE ASR R1  ;RT JUSTIFY DATA ASR R1 ASR R1  ;WOULDN'T EIS BE NICE ASR R1  ;...ALL THAT = ASH 4,R1 AU.SND: MOV R1,@PI.DAT(R0) ;SEND THE DATA TO CALLER BIC #1,UD.CSR ;CLEAR RIF BIT IN CSR ADD #2,PI.DAT(R0) ;SET POINTER AT NEXT WORD IN BUFFER ; ; NOW START NEXT CONVERSION ; AU.DOT: MOV (PC)+,R1 ;GET ADR OF NXT CONVERSION TO START AU.NAD: .WORD 0  ;NEXT BUS ADR TO USE TO START CONVERSION BEQ AU.DON  ;WHEN 0,NO MORE!!! MOV (PC)+,@R1 ;MORE TO DO-SO DO IT!!! AU.NXI: .WORD 0  ;NEXT TO INITIATE CONTROL WD HERE MOV AU.NAD,AU.NAR ;STORE BUS ADR FOR COMPLETION RTN ; ; NOW CALCULATE NEXT CHANNEL TO READ ; AU.CAL: CLR R2  ;INIT TO CALC UDC ADR DEC PI.NUM(R0) ;COUNT DOWN THE NUM TO DO BLT AU.CL9  ;WHEN LT-ALL DONE!!! JSR PC,PI.GET ;GO GET CONVERSION INFO MOV R1,R2  ;COPY DATA BIC #176000,R2 ;CLR ALL BUT CHAN NO OF REQUEST CMP R2,#AU.MAX ;CK CHANNEL FOR RANGE BLT 17$  ;BR IF IN RANGE INC AU.EFG  ;SAVE ERROR STATUS CLR R1  ;...AND GET A ZERO BR AU.SND  ;...AND CALL DONE ON THIS CHANNEL 17$: ASR R2  ;CHAN # OK-CONV TO OFFSET FORM UDC BASE ASR R2  ;...OF FIRST ANALOG MODULE(AU.BAS) BIC #1,R2  ;MUST BE EVEN-WORD ADR BIC #107770,R1 ;CLR ALL BUT GAIN AND CHAN LST 3 ASLB R1  ;MOVE CHANNEL WITH-IN MODULE OVER ASLB R1  ;...TO WHERE THE HDWR WANTS IT!!! ASLB R1 ASLB R1 BIS #100000,R1 ;SET ADU01 GO BIT!!! MOV R1,AU.NXI ;SAVE AS NEXT CONT. WD. TO INITIATE ADD #AU.BAS+AU.BAS+UD.MOD,R2 ;ADJ TO UNIBUS ADR OF MODULE TO DO. AU.CL9: MOV R2,AU.NAD ;SAVE UNIBUS ADR OR 0 FOR NEXT INTER'P MOV #-2,SY.TO(R0) ;RE-ENABLE TIME-OUT RTS PC ; ; COME HERE WHEN TRANSFER DONE ; AU.DON: MOV (PC)+,R1 ;PICK UP ERROR CODE AU.EFG: .WORD 0  ;ERROR CODE STORED HERE IF FOUND BEQ UD.S09  ;IF EQUAL-ALL IS WELL BR UD.S10  ;ELSE RETURN ERROR CODE ; .ENDC   ;END OF ADU01 TRANSFER CODE UD.SP: MOV #UD.FMK,R5 ;SET UP LEGAL FUNCTION MASK JSR PC,PI.SPF ;SET UP DDB AND CHECK FUNCTION CMP R2,#4  ;TEST FOR INPUT OR OUTPUT FUNCTION BEQ UD.S13  ;IF THIS NO CMP R2,#5  ;IS IT A 5 BEQ UD.S13  ;YES BITB #SY.DWN,SY.DFL(R0);TEST FOR DEVICE DOWN BNE UD.S10  ;IF NE YES-TAKE ERROR EXIT ; ;$; PATCH FOR ANALOG SUPPORT ; .IFDF AU.BAS ; CMP R2,#3  ;$;LOOK FOR ANALOG READ FIRST BGT AU.XFR  ;$;CALL ANALOG TRANS FER IF YES ; .ENDC ;FOR ANALOG ; UD.S01: DEC PI.NUM(R0) ;DECREMENT COUNT OF ITEMS BLT UD.S09  ;IF LT DONE MOV PI.ADR(R0),R1 ;GET ADDRESS OF TERMINAL DATA CLR R3 BISB (R1)+,R3 ;SET MODULE ADDRESS CMP R3,#UD.CHN ;TEST FOR LEGAL MODULE ADDRESS BHIS UD.S10  ;IF HIS ERROR ASL R3  ;MAKE WORD INDEX MOVB (R1)+,R4 ;GET SIZE-1 AND RIGHT BIT MOV R1,PI.ADR(R0) ;SAVE ADDRESS OF TERMINAL DATA MOV #36,R1  ;ASSUME 16 BIT READ OR WRITE CLR R5  ; BIT #2,R2  ;TEST FUNCTION BEQ UD.S02  ;IF EQ 16 BIT TRANSFER MOV R4,R5  ;GET RIGHT BIT OF FIELD BIC #177760,R5 ;CLEAR EXCESS MOV R4,R1  ;GET SIZE-1 TIMES 2 ASR R1  ; ASR R1  ; ASR R1  ; BIC #177741,R1 ;CLEAR EXCESS BITS MOV R1,R4  ;CHECK FOR LEGAL FIELD DEFINITION ASR R4  ; ADD R5,R4  ; CMP R4,#17  ; BHI UD.S10  ;IF HI ERROR UD.S02: BIT #1,R2  ;TEST FOR READ OR WRITE BEQ UD.S06  ;IF EQ READ MOV UD.MSK(R1),R1 ;MASK WORD TO R1 MOV @PI.DAT(R0),R4 ;GET DATA TO WRITE BIC R1,R4  ;CLEAR EXCESS BITS COM R1  ;COMPLEMENT MASK WORD UD.S03: DEC R5  ;DECREMENT SHIFT COUNT BLT UD.S04  ;IF LT DONE ASL R1  ;SHIFT MASK ASL R4  ;SHIFT DATA BR UD.S03  ; UD.S04: BIC R1,UD.PRV(R3) ;CLEAR FIELD BIS R4,UD.PRV(R3) ;INSERT ZE OLE DATA FILED MOV UD.PRV(R3),UD.MOD(R3);WRITE VALUE TO MODULE UD.S05: ADD #2,PI.DAT(R0) ;UPDAT ADDRESS OF DATA BR UD.S01  ;GO AROUND AGAIN UD.S06: MOV UD.MOD(R3),R4 ;READ MODULE MOV R4,UD.PRV(R3) ;SAVE CURRENT STATUS UD.S07: DEC R5  ;DECREMENT SHIFT COUNT BLT UD.S08  ;IF LT DONE ASR R4  ;SHIFT DATA BR UD.S07  ; UD.S08: BIC UD.MSK(R1),R4 ;CLEAR EXCESS BITS MOV R4,@PI.DAT(R0) ;STORE INPUT FIELD BR UD.S05  ; UD.S09: MOV #1,R1  ;FINAL STATUS IS SUCESSFUL BR UD.S11 ; UD.S10: MOV #3,R1  ;FINAL STATUS IS ERROR UD.S11: MOV R1,@PI.ERR(R0) ;STORE FINAL STATUS UD.S12: JMP @14(R0)  ;COMPLETION EXIT ; ; GET INTERRUPT DATA OR READ PREVIOUS ; UD.S13: BNE UD.S17  ;IF NE READ PREVIOUS MOV #20,@PI.FAD(R0) ;SET FLAG TO NONE FOUND MOV PI.DAT(R0),R2 ;SET DATA ARRAY ADDRESS CLR R1  ;START AT FRONT OF TABLE UD.S14: MOV UD.COS(R1),(R2)+;MOVE A CHANGE OF STATE WORD BNE UD.S15  ;IF NE HIT ONE CMP (R1)+,-(R2) ;ADJUST BOTH REGISTERS CMP R1,#UDNIM2 ;TEST FOR END OF LIST. BLO UD.S14  ;IF LO GO AGAIN MOV #-1,UD.FLG ;RESET REQUEST FLAG BIS #2,UD.CSR ;TURN ON DEFFERED INTERRUPTS BR UD.S09  ;TAKE GOOD EXIT UD.S15: CLR UD.COS(R1) ;CLEAR ENTRY ASR R1  ;MAKE BYTE INDEX MOVB UD.IMD(R1),R1 ;GET MODULE NUMBER BIC #177400,R1 ;CLEAR EXCESS BITS MOVB UD.GEN(R1),R3 ;GET MODULE INFORMATION MOV R3,R4  ;COPY INFO SWAB R4  ;SWAP HALVES CLRB R4  ;CLEAR LOW BYTE BIS R1,R4  ;INSERT MODULE NUMBER MOV R4,@PI.ADR(R0) ;STORE MODULE INFO AND NUMBER ASL R1  ;MAKE MODULE NUMBER WORD INDEX BIC #177760,R3 ;CLEAR ALL BUT GENERIC CODE MOV R3,@PI.FAD(R0) ;STORE GENERIC CODE CMP R3,#4  ;TEST TYPE OF CODE BLO UD.S16  ;IF LO CONTACT INTERRUPT MOV UD.MOD(R1),(R2)+;READ CLOCK MODULE INTO ARRAY BR UD.S09  ;EXIT UD.S16: MOV UD.PRV(R1),(R2)+;GET PREVIOUS STATUS BR UD.S09  ;EXIT ; ; READ PREVIOUS STATUS ; UD.S17: MOV PI.ADR(R0),R1 ;ADDRESS OF TERMINAL DATA MOV PI.DAT(R0),R2 ;ADDRESS OF DATA ARRAY UD.S18: DEC PI.NUM(R0) ;DECREMENT NUMBER REMAINING BLT UD.S09  ;IF LT DONE CLR R3 BISB (R1)+,R3 ;SET MODULE ADDRESS CMP R3,#UD.CHN ;TEST FOR LEGAL ADDRESS BHIS UD.S10  ;IF HIS ERROR MOVB UD.GEN(R3),(R1)+;STORE MODULE INFORMATION ASL R3  ;MAKE WORD INDEX MOV UD.PRV(R3),(R2)+;STORE PREVIOUS STATE BR UD.S18  ;GO AROUND AGAIN ; ; UDC-11 INTERRUPT ROUTINE ; UD.N00: JSR R5,STRG  ;SAVE REGISTERS MOVB UD+6,PS  ;LOWER PRIORITY TO DEVICE LEVEL MOV #SRTI,-(SP) ;$;SET ADR SO EXIT DONE BY RETURN MACRO MOV #UD.CSR,R5 ;GET CSR ADDRESS BIT #140000,(R5) ;TEST FOR ERRORS BEQ UD.N02  ;IF EQ NO UD.N01: MOV #UDDDB,R0 ;GET DDB ADDRESS MOVB SY.RTN(R0),SY.SCB+1(R0) ;SET TASK# JSR R5,DV.A2 ;DECLARE DEVICE DOWN NOP   ; MOV UD,R0  ;GET DDB ADR OR 0 IF NOT BUSY BEQ UD.N13  ;EXIT TO SYSTEM BR UD.S11  ;GIVE THE REQUESTOR THE BAD NEWS UD.N02: BIT #20000,(R5) ;TEST FOR IMMEDIATE INTERRUPT BNE UD.N03  ;IF NE YES MOV -(R5),R1 ;READ SCAN REGISTER BMI UD.S13  ;IF DISPLACED SCAN DISMISS INT BIS #100000,R1 ;SET DEFERRED FLAG BR UD.N04  ; UD.N03: MOV -(R5),R1 ;READ SCAN REGISTER BIC #100000,R1 ;RESET DEFERRED FLAG UD.N04: CLR R3  ;START AT FRONT OF TABLE UD.N05: CMP R3,#UD.NIM ;TEST FOR END BHIS UD.N01  ;ERROR SHOULD NEVER HAPPEN CMPB UD.IMD(R3),R1 ;TEST FOR MATCH BEQ UD.N06  ;IF EQ HIT INC R3  ;BUMP TO NEXT ENTRY BR UD.N05  ;AND TRY AGAIN UD.N06: ASL R3  ;MAKE WORD INDEX CLR R5 BISB R1,R5  ;SET MODULE NUMBER MOV R1,R2  ;COPY SCAN REGISTER SWAB R2  ;SWAP HALVES MOVB R2,UD.GEN(R5) ;SAVE MODULE INFO BIC #177760,R2 ;CLEAR ALL BUT GENERIC CODE ASL R5  ;MAKE WORD INDEX INC UD.CSR  ;SET RIF BIT TO RESET INTERRUPT CMP R2,#4  ;WHICH TYPE OF MODULE? BLO UD.N07  ;IF LO CONTACT INTERRUPT ; .IFDF AU.BAS ; CMP #AU.GEN,R2 ;$;LOOK FOR ANALOG MODULE BNE UD.N6X  ;BR IF NOT MOV UD,R0  ;GET ADR OF DDB FROM PROLOG BEQ UD.N01  ;IF EQUAL NOTHING'S HAPPENNING-ERROR JMP AU.GET  ;IF OK-GO GET DATA UD.N6X:  ;REFERENCE TAG ; .ENDC INC UD.COS(R3) ;COUNT UP NO INTERRUPTS BETWEEN GETUDC'S TST UD.MOD(R5) ;RESET THE INTERRUPT BR UD.N10  ; UD.N07: MOV UD.MOD(R5),R2 ;GET CURRENT STATUS MOV UD.PRV(R5),R4 ;GET PREVIOUS STATUS MOV R2,UD.PRV(R5) ;UPDATE PREVIOUS TO CURRENT MOV R2,R0  ;COPY CURRENT STATUS BIC R4,R2  ;NOT.PREVIOUS.AND.CURRENT BIC R0,R4  ;NOT.CURRENT.AND.PREVIOUS BIS R2,R4  ;FORM EXCLUSIVE OR COM R1  ;NOT.SCAN REGISTER BIT #60000,R1 ;TEST FOR BOTH PCL AND POP BEQ UD.N09  ;IF EQ A WINNER BIT #40000,R1 ;TEST FOR PCL BNE UD.N08  ;IF NE NO COM R0  ;NOT.CURRENT UD.N08: BIC R0,R4  ;CLEAR UNWANTED BITS BEQ UD.N12  ;IF EQ NO HIT UD.N09: BIS R4,UD.COS(R3) ;SET CHANGED BITS COM R1  ;COMPLEMENT SCAN REGISTER UD.N10: TST R1  ;TEST INTERRUPT TYPE BPL UD.N14  ;IF PL IMMEDIATE BIC #2,UD.CSR ;DISABLE DEFERRED INTS UD.N14: INC UD.FLG  ;REQUEST ALREADY MADE? BGT UD.N11  ;IF GT YES MOVB #UDCT,R0 ;ACTIVATE UDC TASK CLR R2  ;NO DATA JSR R5,HSASI ; NOP   ;IGNOR BAD RETURN UD.N11: CLR UD.FLG  ;MAKE SURE NO OVERRUNS UD.N12: BIC #1,UD.CSR ;CLEAR ENABLE BIT UD.N13: RTS PC  ;EXIT TO SYSTEM ; ; UDC TASK ACTIVATION FLAG ; UD.FLG: .WORD -1  ; ; ; UDC-11 MASK TABLE FOR FIELD READS AND WRITES ; UD.MSK: .WORD 177776  ; .WORD 177774  ; .WORD 177770  ; .WORD 177760  ; .WORD 177740  ; .WORD 177700  ; .WORD 177600  ; .WORD 177400  ; .WORD 177000  ; .WORD 176000  ; .WORD 174000  ; .WORD 170000  ; .WORD 160000  ; .WORD 140000  ; .WORD 100000  ; .WORD 0  ; ; ; UDC-11 DDB ; 0,0   ;ACTIVE DDB CHAIN ;**NEW** .WORD 0  ;CHAIN LINK .WORD 0,0  ;LEVEL COUNTS .WORD UD  ;DRIVER ADDRESS UDDDB: .WORD 0,0,0,0,0,0,0,0,0,0,0,0; .BYTE 0  ;TMP STORE FOR FCN CODE .BYTE 10  ;SUSPEND NUMBER .WORD 0,0,0,0,0 ; .BYTE 0  ;TASK RESERVED FOR .BYTE SY.DPR  ;FLAGS (PERMENANT DDB) .WORD 0,0  ;SCB .WORD 0  ;TIME OUT COUNTS .END