.MCALL .MODULE .MODULE DT,VERSION=07,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 ; DT$CSR (177340) CSR ; DT$VEC (204) Vector ; ; MMG$T std conditional ; TIM$IT std conditional (no code effects) ; ERL$G std conditional ;- .SBTTL MACROS AND DEFINITIONS ; 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 .MCALL .DRDEF .ASSUME .DRDEF DT,1,FILST$,578.,177340,214,DMA=NO .DRPTR .DREST CLASS=DVC.DK TCST =: DT$CSR ;CONTROL AND STATUS REGISTER TCCM =: TCST+2 ;COMMAND REGISTER TCWC =: TCCM+2 ;WORD COUNT REGISTER TCBA =: TCWC+2 ;BUS ADDRESS REGISTER TCDT =: TCBA+2 ;DATA REGISTER DTCNT =: 8. ;RETRY COUNT DTNREG =: 5 ;# OR REGISTERS TO READ FOR ERROR LOB .SBTTL INSTALLATION CODE .DRINS DT BR 10$ ;Data device installation check .ASSUME . EQ INSSYS BR 20$ ;System device installation check 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 overflow> .SBTTL DRIVER ENTRY .DRBEG DT MOV #DTCNT,(PC)+ ;INIT THE RETRY COUNT DTTRY: .WORD 0 ;RETRY COUNTER CLR @#TCCM ;CLEAR ERROR REGISTER ON ENTRY. BR DTCMN ;INTERRUPT SERVICE .IF NE ERL$G DTSTPJ: JMP DTSTOP .DRAST DT,6,DTSTPJ .IFF .DRAST DT,6,DTSTOP ;AST ENTRY TABLES .ENDC ;NE ERL$G DTCMN: MOV R0,-(SP) MOV DTCQE,R5 ;RO POINTS TO Q ELEMENT MOV #TCCM,R4 ;R4 POINTS TO CONTROL REGISTER MOV (R5)+,-(SP) ;DESIRED BLOCK # ONTO STACK MOV (R5)+,R0 ;UNIT # INTO R0 CMP (SP),#DTDSIZ ;TEST IF BLOCK IS TOO BIG. BHIS HERROR ;YES. BIC #^C<3400>,R0 ;ISOLATE UNIT NUMBER BIT #100100,(R4) ;ERROR BIT ON? BMI DTERR ;YES .IF NE ERL$G BNE 1$ JMP RETRY .IFF BEQ RETRY ;IF INTERRUPT IS OFF,WE ARE INITIATING .ENDC ;NE ERL$G 1$: BIT #2,(R4) ;SEARCHING? BEQ DTDONE ;NO-A READ OR WRITE JUST COMPLETED CMP @#TCDT,BWANT ;COMPARE ACTUAL BLOCK TO DESIRED BLOCK BEQ BLKFND ;FOUND IT DIRECT: BLE FORWARD ;SEARCH IN THE FORWARD DIRECTION REVERSE:BIS #4000,R0 ;SET REVERSE BIT SUB #2,(SP) ;SEARCH FOR TW0 BLOCKS BEFORE ONE ;ACTUALLY DESIRED (TO ALLOW ;SPACE FOR THE TURN-AROUND BR FORWARD ;DON'T SET DELAY INHIBIT FORW1: BIS #10000,R0 ;TAPE IS ALREADY MOVING FORWARD ;SO INHIBIT HARDWARE DELAY FORWARD:BIS #103,R0 ;INTERRUPT ENABLE,RNUM,AND GO MOV (SP)+,BWANT ;REMEMBER THE BLOCK WE ARE LOOKING FOR RETRNI: MOV R0,(R4) ;TELL CONTROLLER TO GO MOV (SP)+,R0 ;RESTORE R0 RTS PC ;BACK INTO MONITOR ENDZR: BIT #4000,(R4) ;WERE WE IN REVERSE? BEQ REVERSE ;NO-REVERSE TAPE BLKFND: BIT #4000,(R4) ;WERE WE GOING FORWARD? BNE FORWARD ;NO-WE HAVE TO TURN AROUND ; INITIATE READ/WRITE REQUEST BIS #10115,R0 ;ASSUME WRITE .IF EQ MMG$T MOV (R5)+,@#TCBA ;CORE ADDRESS .IFF JSR PC,@$MPPTR ;CONVERT TO PHYSICAL ADDRESS MOV (SP)+,@#TCBA ;MOVE LO 16 BITS INTO TCBA MOV R0,(PC)+ ;SAVE CURRENT COMMAND WORD 10$: .BLKW MOV (SP)+,R0 ;GET HIGH-ORDER ADDRESS BITS <21:18> BIT #1700,R0 ;22-BIT ADDRESS SPECIFIED? BNE HERROR ;YES, NOT VALID FOR THIS CONTROLLER BIS 10$,R0 ;NO, MERGE COMMAND WORD WITH EXTENSION BITS .ENDC ;EQ MMG$T MOV (R5),(SP) ;WORD COUNT (OVER BLOCK #) BMI 1$ ;WRITE WAS A GOOD GUESS BEQ DTDONE ;IF ZERO,SEEK NEG (SP) ;READ-NEGATE WORD COUNT BIC #10,R0 ;SET READ FUNCTION 1$: MOV (SP)+,@#TCWC ;SET WORD COUNT BR RETRNI ; ERROR ROUTINE DTERR: BIT #104000,@#TCST ;ENDZ ERROR? BPL NOTEZ ;NOT ENDZ BIT #2,(R4) ;WERE WE SEARCHING? BNE ENDZR ;YES-REVERSE TAPE NOTEZ: .IF NE ERL$G BIT #114400,@#TCST ;TEST FOR USER ERRORS BEQ 2$ CLR DTTRY ;0 RETRY SO ERROR IS NOT LOGGED. BR HERROR ;AND BRANCH TO HARD ERROR 2$: MOVB #11,@#TCCM ;STOP DRIVE. TST (SP)+ ;TAKE VALUES OFF STACK TO DO A FORK. MOV (SP)+,R0 ;RESTORE R0,FORK WILL RESTORE THIS ;VALUE OF R0 ON EXIT FROM FORK. ;NOTHING CAN BE ON STACK BETWEEN INTEN&FORK. .FORK DTFBLK ;ENTER ERROR LOGGER AT THE FORK LEVEL. MOV PC,R5 ;GET ADDRESS TO SAVE REGISTERS. ADD #DTRBUF-.,R5 MOV R5,R2 ;SAVE ADDRESS ON R2 FOR EL MOV #DT$CSR,R3 ;R3 = ADDRESS OF REGISTER TO READ MOV #DTNREG,R4 ;R4 = # OF REGISTERS TO READ DTRREG: MOV (R3)+,(R5)+ ;MOVE REGISTERS TO BUFFER DEC R4 ;TEST IF DONE BNE DTRREG ;NO MOV #DTNREG,R3 ;R3 = # OF REGISTERS IN LOW BYTE ADD #DTCNT*400,R3 ;R3 = TOTAL RETRY COUNT IN HIGH BYTE MOV DTCQE,R5 ;SET R5= ADDRESS OF Q ELEMENT. MOV DTTRY,R4 ;SET R4=RETRY COUNT IN LOW BYTE. DEC R4 ADD #DT$COD*400,R4 ; AND =1 IN HIGH BYTE,DT CODE=1 JSR PC,@$ELPTR ;CALL ERROR LOGGER. MOV #TCCM,R4 ;RETURN HERE AND SET R4 TO PREVIOUS VALUE. MOV DTCQE,R5 ;RESTORE R5. MOV R0,-(SP) ;PUT DUMMY VALUE ON STACK,R0 WILL BE ;RESTORED BY FORK. MOV (R5)+,-(SP) ;RESTORE BLOCK ON STACK. MOV (R5)+,R0 ;RESTORE UNIT NUMBER IN R0 BIC #^C<3400>,R0 1$: .ENDC ;NE ERL$G DEC DTTRY ;MORE TRIES LEFT? BGT RETRY ;YES HERROR: MOV DTCQE,R5 ;R5->CURRENT QUEUE ELEMENT BIS #HDERR$,@-(R5) ;NO-SET HARD ERROR BIT ; OPERATION FINISHED DTDONE: TST (SP)+ ;POP BLOCK MOV (SP)+,R0 ;RESTORE R0 .IF NE ERL$G TST DTTRY ;TEST IF ERROR OR SUCCESS. BEQ DTSTOP ;BRANCH ON ERROR. MOVB #11,@#TCCM ;STOP SELECTED DRIVE. .FORK DTFBLK ;ENTER ERROR LOGER AT FORK LEVEL. MOV #DT$COD*400+377,R4 ;SUCCESSFUL TRANSFER,CALL ERROR LOGGER WITH ;R4=1 IN ODD BYTE:DT DEVICE CODE ; 377 IN EVEN BYTE:-1 FOR SUCCESS. MOV DTCQE,R5 ;SET R5=3RD WORD OF Q ELEMENT. JSR PC,@$ELPTR ;CALL ERROR LOGGER. BR DTEXIT ;DON'T RESET R4 ON RETURN .ENDC ;NE ERL$G DTSTOP: MOVB #11,@#TCCM ;STOP SELECTED DRIVE .IF NE ERL$G CLR DTFBLK+2 ;CLEAR FORK BLOCK TO AVOID DISPATCH .ENDC ;NE ERL$G DTEXIT: .DRFIN DT ;GO TO I/O COMPLETION ; RETRY CODE RETRY: TSTB @#TCST ;TAPE UP TO SPEED? BPL 10$ ;NOPE... JMP FORW1 ;YES-AVOID STOPPING TAPE 10$: ADD #4,BWANT ;NO-IT TAKES 4 BLOCKS TO START AND STOP CMP (PC)+,(SP) ;MAKE AN ATTEMPT TO START IN THE BWANT: .WORD 0 ;RIGHT DIRECTION BASED ON LAST BLOCK JMP DIRECT ;DESIRED .IF NE ERL$G DTFBLK: .WORD 0,0,0,0 ;FORK BLOCK. DTRBUF: .BLKW DTNREG ;ERROR LOG STORAGE FOR REGISTERS. .ENDC .SBTTL BOOTSTRAP DRIVER .DRBOT DT,BOOT1,READ . = DTBOOT+40 ;PUT THE JUMP BOOT INTO SYSCOM AREA BOOT1: JMP @#BOOT-DTBOOT ;START THE BOOTSTRAP . = DTBOOT+210 READ: MOV #TCCM,R4 ;R4 -> COMMAND REG MOV #TCDT,R3 ;R3 -> DATA REG 1$: MOV R0,R5 ;COPY BLOCK NUMBER SUB #2,R5 ;SEARCH FOR 2 EARLIER MOV #4003,@R4 ;REVERSE,RNUM 2$: BIT #100200,@R4 ;WAIT TILL BLOCK FOUND BEQ 2$ BMI 6$ CMP R5,@R3 ;IS IT THE DESIRED BLOCK BLT 1$ ;NO,CONTINUE SEARCHING 3$: MOV #3,@R4 ;SEARCH FORWARD (RNUM) 4$: BIT #100200,@R4 ;WAIT BEQ 4$ BMI 6$ CMP R0,@R3 ;DESIRED BLOCK BGT 3$ ;NO-SEARCH FORWARD BLT 1$ ;NO-SEARCH REVERSE MOV R2,-(R3) ;BUFFER ADDRESS NEG R1 MOV R1,-(R3) ;WORD COUNT MOV #5,@R4 ;READ 5$: BIT #100200,@R4 ;WAIT FOR COMPLETION BEQ 5$ BMI BIOERR ;READ ERROR CLR @R4 ;STOP DT (THIS ALSO CLEARS CARRY BIT FOR RET) RTS PC 6$: TST @#DT$CSR ;WHAT KIND OF ERROR ? BPL BIOERR ;NOT END ZONE BIT #4000,@R4 ;REVERSE? BNE 3$ ;THEN GO SEARCH FORWARD BR 1$ ;ELSE SEARCH REVERSE . = DTBOOT+602 BOOT: MOV #10000,SP ;SET STACK POINT MOV @#TCCM,-(SP) ;GET THE CONTROLLER STATUS BIC #^C<3400>,@SP ;STRIP TO UNIT NUMBER SWAB @SP ;UNIT NUMBER IN 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 JSR PC,READ ;GO READ IT IN MOV #READ-DTBOOT,@#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 DT .END