.MCALL .MODULE .MODULE DP,VERSION=09,COMMENT=,AUDIT=YES ; Copyright (c) 1998 by Mentec, Inc., Nashua, NH. ; All rights reserved ; ; This software is furnished under a license for use only on a ; single computer system and may be copied only 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 except for use on such ; system and to one who agrees to these license terms. Title ; to and ownership of the software shall at all times remain ; in Mentec, Inc. ; ; The information in this document is subject to change without ; notice and should not be construed as a commitment by Digital ; Equipment Corporation, or Mentec, Inc. ; ; Digital and Mentec assume no responsibility for the use or ; reliability of its software on equipment which is not supplied ; by Digital or Mentec, and listed in the Software Product ; Description. .SBTTL CONDITIONAL ASSEMBLY SUMMARY ;+ ;COND ; RP0$3 (0) Support RP02/3 ; 0 Support RP02 ; 1 Support RP03 ; ; DP$CSR (176710) CSR ; DP$VEC (254) Vector ; ; EIS$I (MMG$T) SOB instruction (no code effects!) ; 0 simulate SOB ; 1 use SOB ; ; MMG$T std conditional ; TIM$IT std conditional (no code effects) ; ERL$G std conditional ;- .SBTTL MACROS AND DEFINITIONS .MCALL .DRDEF .ADDR .ASSUME .IIF NDF RP0$3, RP0$3 == 0 ;ASSUME RP02 AS DEFAULT .DRDEF DP,21,FILST$,40000.,176710,254,DMA=NO .DRPTR .DREST CLASS=DVC.DK .IIF NDF EIS$I EIS$I=MMG$T .IIF EQ EIS$I .MCALL SOB RPCNT =: 10. ;ERROR RETRY COUNT RPNREG =: 12. ;# OF REGISTERS TO READ FOR ERROR LOG. ; RP CONTROLLER REGISTERS RPDS =: DP$CSR ;DEVICE STATUS RPER =: RPDS+2 ;ERROR RPCS =: RPDS+4 ;CONTROL & STATUS RPWC =: RPDS+6 ;WORD COUNT RPBA =: RPDS+10 ;BUS ADDRESS RPCA =: RPDS+12 ;CYLINDER ADDRESS RPDA =: RPDS+14 ;DISK ADDRESS RPM1 =: RPDS+16 ;MAINTENANCE 1 RPM2 =: RPDS+20 ;MAINTENANCE 2 RPM3 =: RPDS+22 ;MAINTENANCE 3 SUCA =: RPDS+24 ;SELECTED UNIT CYLINDER ADDRESS SILO =: RPDS+26 ;SILO MEMORY ; CONTROL & STATUS BITS CS.GO =: 1 ;GO CS.WRT =: 2 ;WRITE CS.RD =: 4 ;READ CS.WTC =: 6 ;WRITE CHECK CS.SEK =: 10 ;SEEK CS.WTN =: 12 ;WRITE (NO SEEK) CS.HOM =: 14 ;HOME SEEK CS.RDN =: 16 ;READ (NO SEEK) CS.MEM =: 60 ;MEMORY EXTENSION CS.INT =: 100 ;INTERRUPT ENABLE CS.RDY =: 200 ;READY CS.DRV =: 3400 ;DRIVE SELECT CS.HDR =: 4000 ;HEADER CS.MOD =: 10000 ;DECSYSTEM-10 OR PDP-15 FORMAT CS.AIE =: 20000 ;ATTENTION INTERRUPT ENABLE CS.HER =: 40000 ;HARD ERROR CS.ERR =: 100000 ;ERROR ; DEVICE STATUS BITS DS.ATT =: 377 ;ATTENTION, UNITS 0-7 DS.WTP =: 400 ;WRITE PROTECT DS.FUS =: 1000 ;FILE UNSAFE DS.SUW =: 2000 ;SEEK UNDERWAY DS.SIN =: 4000 ;SEEK INCOMPLETE DS.HNF =: 10000 ;HEADER NOT FOUND DS.RP3 =: 20000 ;UNIT IS RP03 DS.ONL =: 40000 ;UNIT ONLINE DS.RDY =: 100000 ;UNIT READY ; RMON REFERENCES SYSPTR =: 54 ; SYSCOM pointer to RMON CONFG2 =: 370 ; second configuration word BUS$ =: 000100 ; PROS$ =: 020000 ; BUS$M =: BUS$!PROS$ ;Mask for type bits BUS$X =: BUS$!PROS$ ;Strange (busless) KXJ BUS$C =: PROS$ ;CTI bus BUS$Q =: BUS$ ;QBUS BUS$U =: 0 ;UNIBUS .SBTTL INSTALLATION CODE .DRINS DP BR 10$ ;Data device installation check .ASSUME . EQ INSSYS BR 20$ ;System device installation check (none) 10$: MOV @#SYSPTR,R0 ; get address of RMON MOV CONFG2(R0),R0 ;Get configuration word for BUS check BIC #^C,R0 ;Isolate bus bits CMP #,R0 ;Running on KXJ? BEQ 30$ ;Yes, don't install CMP #,R0 ;CTI? BEQ 30$ ;Yes, don't install 20$: TST (PC)+ ; clear carry, skip setting carry 30$: SEC ; set carry RETURN .Assume . LE 400,MESSAGE=<;Install area too big> .SBTTL DRIVER ENTRY .DRBEG DP MOV #RPCNT,(PC)+ ;SET RETRY COUNT & CLR HOME SEEK FLG RPTRY: .WORD 0 ;RETRY COUNT & HOME SEEK FLAG ;HIGH ORDER BYTE OF RPTRY IS A FLAG USED FOR ;ERROR RETRY CONTROL ; RPTRY+1=0 MEANS FIRST RETRY SEQUENCE ; >0 MEANS HOME SEEK IN PROGRESS ; <0 MEANS SECOND RETRY SEQUENCE ;ERROR RECOVERY PATH IS 10 RETRIES,HOME SEEK,10 MORE RETRIES RPAGN: CLR @#RPCS MOV #400,@#RPCS CLR @#RPCS ;INITIALIZE CONTROLLER,FIRST TO 0, MOV #400,@#RPCS ;THEN TO 1 SO IT PICKS UP WRITE LOCK CONDITION MOV @DPCQE,R5 ;R5 = BLOCK # OF REQUEST CMP #DPDSIZ,R5 ;IS BLOCK NUMBER LEGAL? BLOS RPERRJ ;NOPE JSR R1,DIV ;R3 = R5/10., R2 = REMAINDER .WORD 10. ; R2=SECTOR MOV R2,R4 ;REMEMBER SECTOR MOV R3,R5 ;SET NEW DIVIDEND JSR R1,DIV ;COMPUTE CYL & TRACK .WORD 20. ; (20. TRACKS/CYL) SWAB R2 ;R2 HIGH BYTE = TRACK BIS R2,R4 ;R4 = TRACK & SECTOR MOV DPCQE,R5 ;R5 -> CURRENT QUEUE ELEMENT (Q.BLKN) TST (R5)+ ;R5 -> UNIT NUMBER (Q.UNIT) .ASSUME Q$BLKN+2 EQ Q$UNIT-1 MOV (R5)+,-(SP) ;SAVE IT (R5 -> Q.BUFF) .ASSUME Q$UNIT-1+2 EQ Q$BUFF BIT #4*400,@SP ;OTHER HALF OF DISK? ;THE FOLLOWING LOCATION GETS PATCHED TO CHANGE THIS HANDLER ;FROM AN RP02 HANDLER TO ONE CAPABLE OF HANDLING RP03'S AS WELL AS ;RP02'S. FOR AN RP02 ONLY HANDLER,SET LOC RP23 TO A "BR 1$". FOR A ;HANDLER CAPABLE OF HANDLING RP02 AND RP03 (MAX OF FOUR UNITS ),SET ;THIS LOCATION TO "BEQ 1$". RP23: .IF EQ RP0$3 BR L1 ;NOPE .IFF BEQ L1 ;YEP .ENDC ;EQ L1 ADD #200.,R3 ;ELSE CYL = CYL + 200. BIC #4*400,@SP ;AND UNIT=UNIT-4 L1: BIC #174377,@SP ;STRIP TO UNIT BUTS CMP R3,#202. ;CYL>202? BLE L5 ;YES-PROCEED WITH OPERATION BIC #3400,@#RPCS ;CLEAR CURRENT DRIVE SELECTION BIS (SP),@#RPCS ;SELECT RQUESTED DRIVE BIT #DS.RP3,@#RPDS ;IS THIS DRIVE AN RP03? BNE L5 ;YES-CYLINDERS > 312 EXIST ADD #6,SP ;NO-THEN WE MUST PREVENT ACCESS TO RPERRJ: BR RPERR ;CYL>202,IN CASE RP11C NOT ECO'D L5: MOV #RPDA,R2 ;PREPARE TO LOAD REGISTERS MOV R4,@R2 ;SET TRACK & SECTOR MOV R3,-(R2) ;SET CYLINDER .IF EQ MMG$T MOV (R5)+,-(R2) ;SET BUS ADDRESS .IFF JSR PC,@$MPPTR ;MAP TO PHYSIACL ADDRESS MOV (SP)+,-(R2) ;SET LOW 16 BITS INTO RPBA MOV (SP)+,R1 ;GET HIGH-ORDER ADDRESS BITS <21:18> BIT #1700,R1 ;22-BIT ADDRESS SPECIFIED? BNE RPERR ;YES, NOT VALID WITH THIS CONTROLLER .ENDC ;EQ MMG$T MOV #CS.INT+CS.WRT+CS.GO,R3 ;ASSUME WRITE .ASSUME Q$BUFF+2 EQ Q$WCNT MOV @R5,-(R2) ;SET WORD COUNT BEQ 3$ ;IT'S A SEEK BMI 2$ ;IT'S INDEED A WRITE NEG @R2 ;ELSE A READ ADD #CS.RD-CS.WRT,R3 2$: BIS (SP)+,R3 ;INSERT UNIT NUMBER .IF NE MMG$T BIS R1,R3 ;SET EXTENDED MEMORY BITS FOR RPCS. .ENDC ;NE MMG$T MOV R3,-(R2) ;START OPERATION RETURN ;AND RETURN TO MONITOR 3$: ADD #CS.SEK-CS.WRT,R3 ;MAKE SEEK OPERATION BR 2$ .SBTTL INTERRUPT SERVICE ENTRY POINT .DRAST DP,5,RPABRT ;DEFINE AST ENTRY TABLE MOV #RPCS,R4 ;R4 -> CONTROL & STATUS BIC #CS.AIE+CS.INT,@R4 ;CLEAR INTERRUPT ENABLE MOVB #DS.ATT,-4(R4) ;CLEAR ATTENTION SUMMARY CLRB -4(R4) ;FOR BOTH OLD & ECO'D CONTROLLERS TSTB RPTRY+1 ;HOME SEEK IN PROGRESS? BGT RPHOME ;YES TST @R4 ;ANY ERRORS? BPL RPDONE ;NOPE .IF NE ERL$G BIT #136006,@#RPER ;TEST FOR USER ERRORS BNE RPERR ;DON'T LOG USER ERRORS. .ENDC ;NE ERL$G DECB RPTRY ;ANY MORE RETRIES? BGT RPFORK ;YES-RETRY TSTB RPTRY+1 ;HAVE WE DONE HOME SEEK FOR THIS ERROR YET? BMI RPERR ;BRANCH IF YES-FATAL ERROR INCB RPTRY+1 ;ELSE SET HOME SEEK IN PROGRESS FLAG BIS #CS.AIE,@R4 ;ENABLE ATTENTION INTERRUPT FROM SEEK DONE MOVB #CS.HOM+CS.INT+CS.GO,@R4 ;AND ISSUE HOME SEEK TO SAME UNIT RTS PC RPHOME: TST @R4 ;HOME SEEK SUCCESSFUL? BMI RPERR ;NO, REPORT AN ERROR MOV #177412,RPTRY ;SET HOME SEEK DONE FLAG AND SET RETRY ;COUNT TO 10. RPFORK: .FORK DPFBLK ;YES, REQUEST A SYSTEM PROCESS .IF NE ERL$G CALL RPERLG ;SET UP REGISTERS TO CALL ERROR LOGGER ;DL06 CALL @$ELPTR ;CALL ERROR LOGGER. ;DON'T NEED TO RESTORE R4 OR R5. .ENDC ;NE ERL$G JMP RPAGN ;THEN RETRY 8 MORE TIMES RPERR: MOV DPCQE,R4 ;R4 -> CURRENT QUEUE ELEMENT .ASSUME Q$BLKN-2 EQ Q$CSW BIS #HDERR$,@-(R4) ;SET HARD ERROR IN CSW RPABRT: MOV #1,@#RPCS ;IDLE CONTROLLER CLR DPFBLK+2 ;DON'T ENTER FORK SERVICE .IF NE ERL$G TSTB RPTRY ;TEST RETRY COUNT FOR HARD ERROR. BNE RPEXIT ;IF NON ZERO,NOT ERROR. CALL RPERLG ;SET UP REGISTERS TO CALL ERROR LOGGER ;DL06 BR RPLOG ;GO LOG THE ERROR ;DL06 RPDONE: MOV #DP$COD*400+377,R4 ;I/O SUCESS,R4=DEVICE ID IN HIGH BYTE. ;=-1 IN LOW BYTE. RPLOG: MOV DPCQE,R5 ;R5->3RD WORD OF Q ELEMENT. .FORK DPFBLK ;CALL ERROR LOGGER AT FORK LEVEL. CALL @$ELPTR .IFF RPDONE: .ENDC ;NE ERL$G RPEXIT: .DRFIN DP ;GO TO I/O COMPLETION DPFBLK: .WORD 0,0,0,0 ;FORK QUEUE ELEMENT .IF NE ERL$G RPRBUF: .BLKW RPNREG ;ERROR LOG STORAGE FOR REGISTERS. .ENDC ;NE ERL$G ; ;DL06+ ;+ ; RPERLG - SETS UP REGISTERS TO CALL ERROR LOGGER WITH EITHER SOFT OR ; HARD ERROR ;- ; .IF NE ERL$G RPERLG: .ADDR #RPRBUF,R5 ;GET ADDRESS TO SAVE REGISTERS. MOV R5,R2 ;SAVE ADDRESS ON R2 FOR EL MOV #DP$CSR,R3 ;R3 = ADDRESS OF REGISTER TO READ MOV #RPNREG,R4 ;R4 = # OF REGISTERS TO READ RPRREG: MOV (R3)+,(R5)+ ;MOVE REGISTERS TO BUFFER SOB R4,RPRREG ;TEST IF DONE MOV #RPNREG,R3 ;R3 = # OF REGISTERS IN LOW BYTE ADD #RPCNT*400,R3 ;R3 = TOTAL RETRY COUNT IN HIGH BYTE ;SOFT ERROR,CALL ERROR LOGGER. MOV DPCQE,R5 ;R5->3RD WORD OF Q ELEMENT MOVB RPTRY,R4 ;R4 LOW BYTE=RETRY COUNT ADD #DP$COD*400,R4 ;R4 HIGH BYTE=DEVICE ID RETURN .ENDC ;NE ERL$G ;DL06- ; DIVIDE ROUTINE ; ; DIVIDES R5 BY @R1, RETURNS: ; QUOTIENT IN R3, REMAINDER IN R2 ; ; CALLED BY: JSR R1,DIV ; .WORD DIV: CLR R3 ;INIT QUOTIENT CLR R2 ;AND REMAINDER TST R5 ;IS DIVIDEND 0? BEQ 4$ ;YES - JUST RETURN NOW COM R3 ;QUOT.=-1 & SET CARRY 1$: ROL R5 ;NORMALIZE BCC 1$ 2$: ROL R2 ;SHIFT & SUBTRACT CMP R2,@R1 BLO 3$ SUB @R1,R2 3$: ROL R3 ASL R5 BNE 2$ COM R3 ;FIX QUOTIENT 4$: TST (R1)+ ;BUMP PAST DIVISOR RTS R1 ;AND RETURN .SBTTL BOOTSTRAP DRIVER .DRBOT DP,BOOT1,READ . = DPBOOT+40 ;PUT THE JUMP BOOT INTO SYSCOM AREA BOOT1: JMP @#BOOT-DPBOOT ;START THE BOOTSTRAP . = DPBOOT+210 READ: MOV R0,R3 ;R3 = BLOCK # JSR R2,DIVIDE ;GET SECTOR NUMBER .WORD 10. ;BY DIVIDING BY 10 MOV R4,-(SP) ;SAVE SECTOR MOV R5,R3 ;SET NEW DIVIDEND JSR R2,DIVIDE ;AND COMPUTE CYL & TRACK .WORD 20. ;BY DIVIDING BY 20 SWAB R4 ;POSITION TRACK IN HIGH BYTE BIS (SP)+,R4 ;AND INSTALL SECTOR MOV #RPDA,R3 ;R3 -> DISK ADRS REG MOV R4,@R3 ;SET TRACK & SECTOR MOV R5,-(R3) ;AND CYLINDER MOV R2,-(R3) ;AND BUS ADDRESS MOV R1,-(R3) ;AND WORD COUNT NEG @R3 ;MAKE NEGATIVE BIC #^C,-(R3) ;CLEAR ALL BUT UNIT # BIS #CS.RD+CS.GO,@R3 ; AND START READ 1$: TSTB @R3 ;WAIT UNTIL TRANSFER COMPLETE BPL 1$ TST @R3 ;ANY ERRORS? BMI BIOERR ;YES MOVB #DS.ATT,@#DP$CSR ;CLEAR UNIT ATTN FOR BOTH CLRB @#DP$CSR ;OLD & ECO'D CONTROLLERS(CLEARS C-BIT FOR RET) RETURN ;ELSE JUST RETURN ; DIVIDE ROUTINE FOR RP HANDLER. ; R5 = R3 / @R2, REMAINDER IN R4 DIVIDE: CLR R5 ;QUOT. = 0 CLR R4 ;REM. = 0 TST R3 ;IS DIVIDEND 0? BEQ 4$ ;YES - JUST RETURN COM R5 ;QUOT. = -1 & SET CARRY 1$: ROL R3 ;NORMALIZE BCC 1$ 2$: ROL R4 ;SHIFT & SUBTRACT CMP R4,@R2 BLO 3$ SUB @R2,R4 3$: ROL R5 ASL R3 BNE 2$ COM R5 ;FIX QUOTIENT 4$: TST (R2)+ RTS R2 . = DPBOOT+602 BOOT: MOV #10000,SP ;SET STACK POINT MOV @#RPCS,-(SP) ;GET CONTROLLER STATUS BIC #^C,@SP ;STRIP TO UNIT NUMBER SWAB @SP ;UNIT NUMBER INTO BITS 2-0 MOV #2,R0 ;READ IN SECOND PART OF BOOT MOV #<4*400>,R1 ;EVERY BLOCK BUT THE ONE WE ARE IN MOV #1000,R2 ;INTO LOCATION 1000 CALL READ ;GO READ IT IN MOV #READ-DPBOOT,@#B$READ ;STORE START LOCATION OF READ ROUTINE MOV #B$DNAM,@#B$DEVN ;STORE RAD50 DEVICE NAME MOV (SP)+,@#B$DEVU ;STORE THE UNIT NUMBER TO BOOT FROM JMP @#B$BOOT ;START SECONDARY BOOT .DREND DP .END