.MCALL .MODULE .MODULE PD,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 ; MMG$T 0 std conditional (must be 0) ; TIM$IT std conditional (no code effects) ; ERL$G std conditional ;- ; Edit History: ; ; 001 15-Jan-80 10:33 Metsch, James (29602) [240,122] ; Recalculate impure area address to enable PDT/130 to boot ; (001) ; 002 27-Jan-81 03:18 PM Martin Gentry [240,121] ; Fix for error logger support as per SPR #11-35060 ; (002) ; 009 23-MAY-89 George Stevens ; Added range check for invalid SPFUNs ; THIS DRIVER IS THE RAM PORTION OF A PDT DRIVER WITH PRIMITIVES IN ROM ; ; AUTHOR: ; ; BILL CLOGHER VERSION 1 ; DARRELL DUFFY VERSION 2 27-APR-78 ; ; MODIFIED BY: ; BARBARA DOERRE VERSION 3 9-JAN-79 ; 1) CHANGED CODE AT ASYNCH ENTRY POINT FOR TU58 PERFORMANCE IMPROVEMENT ; 2) CLEAN-UP ERROR LOGGING ; 3) TEST OF FKFLG BEFORE FORK IN FORK ROUTINE ;- .SBTTL BOOTSTRAP ROUTINE DEFINITIONS .LIST MEB .MCALL .DRDEF .ADDR .ASSUME .DRDEF PD,36,FILST$,512.,0,0,DMA=NO .DRPTR .DREST CLASS=DVC.DK,MOD=DVM.DX ;not true for unsupported PDT130 .DSTATUS=:342 ;EMT CODE FOR .DSTATUS REQUEST ; ROM DEFINITIONS ROMS$T =:173000 ;START OF ROM DEVICE TABLE INFORMATION ROM$ID =:ROMS$T+6 ;FLAG NON-0 IF ROM IS PAGED (NOT SUPPORTED) ROM$TP =:ROM$ID+2 ;PAGE NUMBER OF ROM DEVICE TABLE (IF MAPPED) ROM$DT =:ROM$TP+2 ;POINTER TO DEVICE TABLE FOR FIRST DEVICE ; ROM DEVICE TABLE LAYOUT RD$NDP =:0 ;PAGE NUMBER OF NEXT DEVICE (0 IF NO MORE) RD$NT =:RD$NDP+2 ;POINTER TO NEXT DEVICE TABLE RD$ASC =:RD$NT+2 ;DEVICE NAME (2 CHARACTER ASCII) RD$IMP =:RD$ASC+2 ;SIZE OF IMPURE AREA REQUIRED (WORD COUNT) RD$BST =:RD$IMP+2 ;POINTER TO BOOTSTRAP ROUTINE RD$BSR =:RD$BST+2 ;POINTER TO BOOTSTRAP READ ROUTINE RD$DID =:RD$BSR+2 ;POINTER TO DEVICE CHARACTERISTICS ROUTINE RD$SIO =:RD$DID+2 ;POINTER TO START I/O ROUTINE RD$ABT =:RD$SIO+2 ;POINTER TO ABORT I/O ROUTINE RD$PUP =:RD$ABT+2 ;POINTER TO POWER-UP ROUTINE RD$ISR =:RD$PUP+2 ;POINTER TO INTERRUPT SERVICE ROUTINE BT$IMP =:10000 ;ADDRESS OF IMPURE AREA USED BY BOOTSTRAP DX$COD =:22 ;DSTATUS CODE FOR DX DD$COD =:34 ;DSTATUS CODE FOR DD P3$COD =:36 ;DSTATUS CODE FOR PDT 130 P5$COD =:37 ;DSTATUS CODE FOR PDT 150 .SBTTL INSTALLATION ROUTINE .ASECT . = 200 .ENABL LSB PDINST: BR O.BAD ;QUIT IF NOT SYSTEM DEVICE JSR R4,1$ ;SAVE R4, POINT TO AREA FOR DEVICE INFO DEVTBL: .WORD DEVEND-DEVTBL/2 ;START OF DEVICE TABLE IS SIZE IN WORDS DV$UNT: .BLKW ;UNIT NUMBER DV$ASC: .BLKW ;DEVICE NAME AS 2-CHARACTER ASCII DV$R50: .BLKW ;DEVICE NAME AS RAD50 DV$IMS: .BLKW ;IMPURE AREA SIZE (IN WORDS) DV$DST: .BLKW ;DEVICE STATUS WORD DV$LOS: .BLKW ;LOW ORDER VOLUME SIZE IN BLOCKS DV$HIS: .BLKW ;HIGH ORDER VOLUME SIZE DV$PAG: .BLKW ;ROM PAGE NUMBER OF PRIMITIVE (IF MAPPED ROM) DV$VEC: .BLKW ;VECTOR ADDRESS (LOW 2 BITS = # OF VECTORS) DV$ISR: .BLKW ;POINTER TO INTERRUPT SERVICE ROUTINE DV$PS: .BLKW ;PS FOR INTERRUPT VECTOR DV$PRI: .BLKW ;PRIORITY TO RUN AT (0 TO 7) DEVEND: 1$: MOV @#B$DEVU,R0 ;GET THE SYSTEM DEVICE UNIT NUMBER MOV @#ROM$DT,R1 ;POINT TO DEVICE TABLE FOR FIRST DEVICE ADD #RD$ISR,R1 ; AT ISR VALUE MOV @R1,.INTRP ;HOOK PD DRIVER TO ROM INTERRUPT ROUTINE TST -(R1) ;SKIP POWER UP ROUTINE ADDRESS MOV -(R1),.ABORT ;HOOK PD DRIVER TO ROM ABORT I/O ROUTINE MOV -(R1),.STARI ;HOOK PD DRIVER TO ROM START I/O ROUTINE CALL @-(R1) ;CALL THE DEVICE CHARACTERISTICS ROUTINE MOV (SP)+,R4 ;RESTORE POINTER TO START OF HANDLER BCS O.BAD ;ERROR IF TABLE ERROR TOO SMALL .ADDR #DV$PRI,R2 ;POINT TO DRIVER TABLE SWAB @R2 ;SHIFT THE PRIORITY BITS ASR @R2 ; TO BRING THEM ASR @R2 ; AROUND TO ASR @R2 ; PRIORITY BITS IN CSR BIC @R2,PDPRMS ;SET INTERRUPT ENTRY MASK TO LOWER TO DEV PRI CMP -(R2),-(R2) ;BACK OVER INTERRUPT PS AND ISR ADDRESS MOV -(R2),R1 ;GET THE DEVICE VECTOR ADDRESS AND COUNT TST -(R2) ;BACK OVER ROM PAGE NUMBER TST -(R2) ;IS THE DEVICE LARGER THAN 65535 BLOCKS? BNE O.BAD ;YES, CAN'T USE IT MOV -(R2),54 ;SAVE THE REAL LOW ORDER SIZE IN THIS PREFIX BR INCONT ;SKIP OVER SET OPTION AREA .DSABL LSB .ASSUME . LE 400,<;INSTALL area overflow> .SBTTL SET OPTIONS .DRSET WRITE, 1, O.WP, NO O.WP: NOP ;'WRITE' ENTRY POINT CLR R3 ; CLEAR FLAG N.WP: ;'NOWRITE' ENTRY POINT .ASSUME O.WP+4 EQ N.WP,<;NO option out of place> MOV R3,O.WPF ; SET FLAG CMP R1,#1 ;IS IT VALID? (0 or 1 only) BHI O.BAD ;NOPE... ; NOW TO ALTER THE CODE WHICH WILL BE WRITTEN BACK TO DISK .ADDR #PDWPRO,R0 ;R0-> THE WRITE-PROTECT TABLE ADD R1,R0 ; POINT TO ENTRY MOVB (PC)+,(R0) ;AND SET IT THE WAY THE USER WANTS IT O.WPF: .BLKW 1 ; NOW TO ALTER THE 'LOADED' COPY OF THE DRIVER .ADDR #DEVNAM,R0 ;R0->DEVICE NAME .ADDR #DAREA+1,@SP ;(SP)->.DSTATUS INFO AREA(+physical) EMT .DSTATUS ;*** (.DSTAT #DAREA+1,#DEVNAM) *** BCS O.BAD ;IN CASE IT'S NOT KNOWN MOV DAREA+4,R0 ;LOAD THE ENTRY POINT BEQ O.GOOD ;HANDLER NOT LOADED ADD #PDW1-PDLQE,R0 ;POINT TO ONE-SHOT FLAG MOV #100000,@R0 ;ALLOW ONE MORE WRITE ADD R1,R0 ;ADD IN UNIT OFFSET MOVB O.WPF,PDWPRO-PDW1(R0) ;SET THE UNIT THE WAY THE USER WANTS O.GOOD: TST (PC)+ ;GOOD RETURN (C-BIT CLEAR) O.BAD: SEC ;BAD RETURN (C-BIT SET) RETURN DAREA: .BLKW 4 ;.DSTAT INFORMATION BLOCK DEVNAM: .RAD50 /PD / ;DEVICE NAME .SBTTL INSTALLATION CODE (CONT.) .ENABL LSB INCONT: 2$: MOV -(R2),R0 ;GET DEVICE DSTATUS CODE .IF NE ERL$G MOVB R0,EL$COD+1 ;SAVE DSTATUS CODE FOR ERROR LOGGER .ENDC ;NE ERL$G CMPB R0,#DX$COD ;IS IT A FLOPPY CODE? BNE 3$ ;NOPE ADD #P5$COD-DX$COD,R0 ;YES, CHANGE IT TO PDT 150 CODE 3$: CMPB R0,#DD$COD ;IS IT A TU58 CODE? BNE 4$ ;NOPE ADD #P3$COD-DD$COD,R0 ;YES, CHANGE IT TO PDT 130 CODE 4$: MOV R0,56 ;SET DSTATUS CODE IN THIS PREFIX MOV -(R2),R0 ;GET THE SIZE OF THE IMPURE AREA IN WORDS ASL R0 ;MAKE IT BYTES ; ADD R0,52 ;BUMP THE SIZE OF THE HANDLER IN THIS PREFIX ADD R0,$INOFF ;FIX OFFSET TO $INPTR ADD R0,$FKOFF ;FIX OFFSET TO $FKPTR .IF NE ERL$G ADD R0,$ELOFF ;FIX OFFSET TO $ELPTR .ENDC ;NE ERL$G SUB R0,R4 ;COMPUTE START OF NEW DRIVER MOV R4,10.(SP) ;TELL BSTRAP SUB R0,6.(SP) ; ABOUT THE RELOCATION! .ADDR #RELOC,R2 ;POINT TO RELOC ROUTINE SUB #<1000+RELOCE-RELOC>,R4 ;R4 -> PLACE FOR RELOC ROUTINE MOV #/2,R3 ;GET WORD COUNT OF RELOC ROUTINE 55$: MOV (R2)+,(R4)+ ;MOVE A WORD DEC R3 ;COUNT DOWN BNE 55$ ;CONTINUE UNTIL DONE ;+ ; R4 NOW POINTS TO START OF NEW INSTALL CODE! ;- MOV 52,R3 ;GET SIZE OF HANDLER ADD #1000,R3 ;INCLUDE INSTALLATION CODE IN SIZE CLC ;MAKE BYTE COUNT ROR R3 ; INTO WORD COUNT MOV R4,R5 ;GET START OF ADD R0,R5 ; OLD INSTALL CODE CALL RELOC-RELOCE(R4) ;RELOCATE INSTALL CODE AND HANDLER ;+ ; R4 NOW POINTS TO TOP OF RELOCATED HANDLER (IMPURE AREA FOR ROM CODE) ;- .ADDR #.DDL,R5 ;POINT TO THE DEVICE DRIVER LIST ADD R4,@R5 ;RELOCATE POINTER TO IMPURE AREA CLR @(R5)+ ;CLEAR FIRST WORD OF AREA CLR (R5)+ ;CLEAR LQE POINTER MOV #.DDLEN-.DDLCP/2,R3 ;GET COUNT OF POINTERS TO RELOCATE 5$: ADD R4,(R5)+ ;RELOCATE A POINTER DEC R3 ;MORE? BNE 5$ ;LOOP FOR ALL MOV R1,R2 ;COPY VECTOR ADDRESS AND COUNT BIC #^C<3>,R2 ;ISOLATE COUNT OF NUMBER OF VECTORS - 1 BIC R2,R1 ;FIX THE VECTOR ADDRESS 6$: MOV R1,(R5)+ ;SAVE A VECTOR ADDRESS CMP (R5)+,(R5)+ ;SKIP ENTRY OFFSET AND NEW PS VALUE CMP (R1)+,(R1)+ ;ADVANCE VECTOR ADDRESS TO NEXT VECTOR DEC R2 ;MORE VECTORS? BPL 6$ ;YES ;CLR @R5 ;ZERO IS ASSEMBLED IN TO END THE TABLE BR O.GOOD ;SUCCESS, RELOC: MOV (R5)+,(R4)+ ;MOVE A WORD DOWN IN MEMORY DEC R3 ;COUNT DOWN BNE RELOC ;CONTINUE UNTIL DONE SUB R0,@SP ;RETURN ADDRESS HAS BEEN RELOCATED! RETURN ;RETURN TO RELOCATED CODE RELOCE: .ASSUME . LE 1000,<;SET area overflow> .DSABL LSB .SBTTL START I/O ENTRY .ENABL LSB .DRBEG PD BR 5$ ; SKIP TABLE PDWPRO: .BYTE 0,0 ;WRITE PROTECT TABLE .ASSUME . LE PDSTRT+1000,<;SET object not in block 1> 5$: MOV PDCQE,R4 ;R4->QUEUE ELEMENT TSTB Q$FUNC(R4) ;IS THIS A SPECIAL FUNTION REQUEST BEQ 6$ ;BRANCH IF NOT CMPB #375,Q$FUNC(R4) ;VALID SPFUN? BHI INVSPF ;BRANCH IF SO 6$: TST Q$WCNT(R4) ;WRITE? BPL 10$ ;NOPE... ASL (PC)+ ; CHECK WRITE ANYWAY ONE-SHOT PDW1: .WORD .-. ; 100000 MEANS WRITE ANYWAY .ASSUME . LE PDSTRT+1000,<;SET object not in block 1> BCS 10$ ;SKIP TEST IF WRITE ANYWAY MOVB Q$UNIT(R4),R4 ;FIND OUT WHICH UNIT BIC #<^C7>,R4 .ADDR #PDWPRO,R4,ADD ;ADD ADDRESS OF WRITE-PROTECT TABLE TSTB (R4) ;IS UNIT WRITE PROTECTED? BNE ERROR ;YES... ; FALL THROUGH IF NO... 10$: .ADDR #.DDL,R5 ;MAKE POINTER TO DDL LIST MOV PDCQE,.DDLQ ;LOAD QUEUE ELEMENT POINTER INTO DRIVER LIST CALL @(PC)+ ;CALL ROM TO START I/O, RETURNS ONLY IF ERROR .STARI: .WORD 0 ;**BOOT** POINTER TO ROM START I/O ROUTINE .ASSUME . LE PDSTRT+1000,<;SET object not in block 1> ERROR: MOV PDCQE,R4 ;ERROR, R4 -> CURRENT QUEUE ELEMENT BIS #HDERR$,@-(R4) ;SET HARD ERROR BIT IN CSW INVSPF: BR PDEXIT ;EXIT ON HARD ERROR .SBTTL INTERRUPT ENTRY .ENABL LSB ;.DRAST PD,PDPRI,PDABRT ;AST ENTRY POINT BR PDABRT ;ABORT ENTRY POINT PDINT:: BCS 1$ ;IF C=1, SKIP THE .INTEN $INOFF = .+2 ;ADDRESS OF OFFSET TO $INPTR JSR R5,@$INPTR ;CALL MONITOR INTERRUPT ENTRY POINT PDPRMS: .WORD 340 ;PRIORITY MASK (FILLED IN BY BOOT) .ASSUME . LE PDSTRT+1000,<;SET object not in block 1> CLR FKFLG ;CLEAR FORK FLAG .ADDR #.DDL,R5 ;FORM POINTER TO DEVICE DRIVER LIST JMP @(PC)+ ;GO TO ROM INTERRUPT SERVICE, RETURNS FOR US .INTRP: .WORD 0 ;**BOOT** POINTER TO ROM INTERRUPT SERVICE ; FAST ENTRY FOR HIGH SPEED INTERRUPT PROCESSING 1$: MOV R4,-(SP) ;SAVE R4 MOV R5,-(SP) ;SAVE R5 .ADDR #.DDL,R5 ;FORM POINTER TO DEVICE DRIVER LIST CALL @.INTRP ;CALL THE ROM INTERRUPT SERVICE MOV (SP)+,R5 ;RESTORE R5 MOV (SP)+,R4 ;RESTORE R4 RTI ;RETURN FROM INTERRUPT .DSABL LSB .SBTTL COMPLETION EXIT COMPLT: BCS ERROR ;IF CS, ERROR .IF NE ERL$G CALL FORK ;NO, MUST BE AT FORK LEVEL FOR ERROR LOGGING MOV (PC)+,R4 ;SUCCESSFUL I/O - CALL ERROR LOGGER EL$COD: .BYTE -1,0 ;*BOOT* HIGH BYTE = DEVICE ID, LOW BYTE = -1 .ASSUME . LE PDSTRT+1000,<;SET object not in block 1> CALL ERLOG ;CALL ERROR LOGGER FOR SUCCESS .ENDC ;NE ERL$G PDEXIT: .DRFIN PD ;EXIT TO COMPLETION ; ABORT ENTRY PDABRT: .ADDR #.DDL,R5 ;FORM PIC POINTER TO DEVICE DRIVER LIST CALL @(PC)+ ;CALL ABORT I/O ROUTINE IN ROM PRIMITIVE .ABORT: .WORD 0 ;**BOOT** POINTER TO ROM ABORT I/O ROUTINE .ASSUME . LE PDSTRT+1000,<;SET object not in block 1> CLR PDFBLK+2 ;ENSURE THAT WE DON'T COME BACK FROM .FORK BR PDEXIT ;EXIT .SBTTL FORK ROUTINE ;+ ; FORK - DO A .FORK FOR THE ROM ; ; R0-R3 = SAME AS AT INTERRUPT TIME ; R4 = UNDEFINED ; R5 -> DEVICE DRIVER LIST ; SP -> SAME AS AT INTERRUPT DISPATCH TIME ; FKFLG = 0 (NO .FORK DONE YET) ; ; JSR PC,FORK ; ; R0-R3 = UNDEFINED, AVAILABLE FOR USE ; R4-R5 = SAME AS WHEN FORK WAS CALLED ; SP -> UNSPECIFIED (BUT NOT THE BE SAME AS WHEN FORK WAS CALLED) ; PRIORITY = 0 (BELOW INTERRUPT LEVEL, ABOVE COMPLETION ACTIVITY) ; FKFLG <> 0 (INDICATES A .FORK HAS BEEN DONE) ;- FORK: TST (PC)+ ;FORK DONE YET? FKFLG: .WORD 0 ;FLAG = 0 IF NO FORK YET, <> 0 IF AT FORK LVL BNE 1$ ;YES, DON'T FORK AGAIN MOV (SP)+,FKFLG ;SAVE RETURN ADDR, POP TO FIX STACK, SET FLAG $FKOFF = .+2 ;OFFSET TO $FKPTR JSR R5,@$FKPTR ;DO A .FORK .WORD PDFBLK-. ;POINTER TO FORK BLOCK MOV FKFLG,-(SP) ;STACK THE RETURN ADDRESS 1$: RETURN ;WE ONLY DO IT ONCE PDFBLK: .BLKW 4 ;FORK BLOCK .SBTTL ERROR LOGGER ;+ ; ERLOG - LOG ERRORS OR SUCCESSES THROUGH THE RT-11 ERROR LOG SUPPORT ; ; R2 -> BUFFER OF REGISTERS IN IMPURE AREA ; R3 = <15-8> TOTAL RETRY COUNT ; <7-0> NUMBER OF REGISTERS TO LOG ; R4 = <15-8> DEVICE ID (AS IN DSTATUS WORD) ; <7-0> CODE: -1 => SUCCESS ; 0 => HARDWARE ERROR ; >0 => SOFT ERROR ; R5 -> DEVICE DRIVER LIST IN THIS DRIVER ; ; JSR PC,ERLOG ; ; AFTER THE ERROR/SUCCESS IS LOGGED, ALL REGISTERS ARE PRESERVED ;- ERLOG: .IF NE ERL$G MOV R5,-(SP) ;SAVE DEVICE DRIVER LIST POINTER MOV PDCQE,R5 ;POINT TO THIRD WORD OF CURRENT QUEUE ELEMENT $ELOFF = .+2 ;ADDRESS OF OFFSET TO $ELPTR CALL @$ELPTR ;CALL THE ERROR LOGGER IF IT'S AROUNE MOV (SP)+,R5 ;RESTORE DDL POINTER .ENDC ;NE ERL$G SYNCH: TIMOUT: XPGLNK: ERRPT: RETURN .SBTTL DEVICE DRIVER LIST ; DEVICE DRIVER LIST FOR ROM - ENTRIES RELOCATED BY THE BOOTSTRAP .DDL: .WORD ENDCOD-IMPUR ;ADDRESS OF IMPURE AREA WHICH ROM CAN USE .DDLQ: .WORD 0 ; -> THIRD WORD OF CURRENT QUEUE ELEMENT .DDLCP: .WORD COMPLT-IMPUR ; -> I/O COMPLETION ROUTINE .DDLFR: .WORD FORK-IMPUR ; -> .FORK ROUTINE .DDLSY: .WORD SYNCH-IMPUR ; -> .SYNCH ROUTINE .DDLEL: .WORD ERLOG-IMPUR ; -> ERROR LOGGING ROUTINE .DDLTM: .WORD TIMOUT-IMPUR ; -> DEVICE I/O TIMEOUT ROUTINE .DDLXP: .WORD XPGLNK-IMPUR ; -> CROSS PAGE LINK ROUTINE FOR MAPPED ROMS .DDLER: .WORD ERRPT-IMPUR ; -> (NON-HARDWARE) ERROR REPORTING ROUTINE .DDLOP: .WORD OPTLST-IMPUR ; -> LIST OF USER-SPECIFIABLE SET OPTIONS .DDLEN: .ASSUME . LE PDSTRT+1000,<;SET object not in block 1> .DRVTB PD,0,PDINT ;MULTI-VECTOR TABLE (FILLED IN BY BOOT) .DRVTB ,0,PDINT ;SECOND .DRVTB ,0,PDINT ;THIRD .DRVTB ,0,PDINT ;FOURTH OPTLST: .WORD 0 ;NULL LIST ENDCOD: .SBTTL BOOTSTRAP DRIVER .DRBOT PD,BOOT1,READ IMPUR == PDEND ;IMPURE AREA GOES AT THE END OF THE DRIVER . = PDBOOT+40 ;PUT THE JUMP BOOT INTO SYSCOM AREA BOOT1: JMP @#BOOT-PDBOOT ;START THE BOOTSTRAP . = PDBOOT+550 READ: MOV @#ROM$DT,R4 ;POINT TO DEVICE TABLE IN ROM MOV #BT$IMP+2,R5 ;POINT TO BOOTSTRAP'S IMPURE AREA + 2 MOV @#B$DEVU,R3 ;GET DEVICE UNIT NUMBER CALL @RD$BSR(R4) ;USE THE BOOT READ ROUTINE BCS BIOERR ;HARD HALT ON ERROR ;CLC ;MAKE SURE CARRY BIT IS CLEAR BEFORE RETURN RETURN BOOT: MOV #10000,SP ;SET STACK POINTER MOV R0,-(SP) ;STACK THE UNIT NUMBER BIC #^C<7>,@SP ;ISOLATE IT MOV @SP,@#B$DEVU ;SET IT FOR THE READ ROUTINE 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-PDBOOT,@#B$READ ;STORE START LOCATION FOR READ ROUTINE MOV #B$DNAM,@#B$DEVN ;STORE RAD50 DEVICE NAME MOV (SP)+,@#B$DEVU ;STORE THE UNIT NUMBER JMP @#B$BOOT ;START SECONDARY BOOT .DREND PD .END