; File: BOOT50.MAC Secundairy bootstrap for Multiprocessor V5 .TITLE BOOTSTRAP READ ROUTINE ;----------------------------- .ENABL LC ; PURPOSE: Boot of remote system disk. ; FUNCTION: - Asks password ; - Asks RSP device number( for this program limited to 0-7). ; - Then reads bootstrap of remote system disk (reads block 0) ; and executes it ; ATTENTION: The following code should not exceed 256. words ; ********** when assembled. Otherwise bootstrapping will not ; work!! (file SY:xxBOOT.SYS size should be 2 blocks). ; ========================================== ; 1. Set NPASSW to the nr. of characters in the PASSWORD. ; 2. Code the password and scramble numbers in PASWRD: and PATTRN: entry. ; (The scramble nrs. prevent that the password could be read by dumping ; or deassembling the binairy boot-file, present on the host system disk!) ; 3. Select the appropriate hardware, see INT values. ; For interface IO-page addresses check PD$CSR setting! ; 4. Create the bootstrap file according to: ; Set the conditional TEST to: TEST=0 ; MAC BOOT50 ; LINK/EXE:SY:xxBOOT.SYS BOOT50 ; CONDITIONALS: ;-------------- NPASSW=4. ;Nr. of chars in password. TEST = 0 ;If =1 then can be run as test prog under RT-11 ;INT = 1 ;Hardware DR(V)-11(C) INT = 2 ;Hardware WB(V)-11 ;INT = 3 ;Hardware Qnector CKS = 1 ;1=enable checksum calculation, 0=minimal error checking. .IIF NE,TEST .MCALL .EXIT ; DEFENITIONS: ;------------- RCSR = 177560 ;Terminal console address RDBR = RCSR+2 XCSR = RCSR+4 XDBR = RCSR+6 PDCNT=7. R$INIT=4 R$DATA=1 R$DSIZ=256. R$MSG=2 R$MSIZ=5 R$$RED=2 CHECK=125252 BOOT:: .IIF NE,TEST BIC #100,@#RCSR QUERY: MOV #PASTXT,R1 CALL PUTSTR CALL GETPAS BCS QUERY MOV #NMBTXT,R1 CALL PUTSTR CALL GETNMB MOV R1,UNITNR READ: MOV #PDCNT,RTRCNT BRESTR: CLR B$BLK ;Contains blocknr. to read MOV #256.,B$WCNT ; " nr. words to read MOV R1,B$UNT .IF EQ,TEST CLR R2 ;R2 = Mem. buff. address, start at 000000 .IFF MOV #BUFFER,R2 .ENDC ;TEST .IF LE,INT-2 WB=0 .IIF NE,INT-1 WB=1 .SBTTL BOOTSTRAP READ ROUTINE for DR(V)-11(C)/WB(V)-11 ;------------------------------------------------------ .IF EQ,WB PD$CSR=167770 ;status .IFF PD$CSR=175610+4 ;Output status WB .ENDC ;WB MOV #PD$CSR,R0 ;Output status reg. WAIT: TSTB @R0 ;Output ready? BPL WAIT .IF EQ,WB TST 4(R0) ;clear input reg. .IFF TST -2(R0) ;clear input reg. .ENDC ;WB ; ; Send command packet. ; .if NE,CKS CLR R4 ;Clear checksum=R4. .iff MOV #CHECK,R4 ;Set check pattern in R4. .endc MOV #B$PKT,R5 ;Point to packet. 1$: MOV (R5)+,R3 ;Get packet word. .if NE,CKS ADD R3,R4 ;update ADC R4 ; checksum. .endc CALL BCHROS ;send word CMP R5,#B$BLK ;End of packet BLOS 1$ ;no MOV R4,R3 ;And send CALL BCHROS ; Checksum ; ; Receive bootstrap data and store them. ; BRDPKT: CALL BICHR ;R1 contains receiv. word. MOV #256.,R4 ;Set to full packet count. TSTB R3 ;O.K. BEQ 3$ ;Yes, then go. CLR R4 ;No. BISB R3,R4 ;R3 " swapped R1, packetwordcnt. 3$: .if NE,CKS MOV R1,R5 ;init checksum .iff MOV #CHECK,R5 ;init checksum .endc CMPB R1,#1 ;data packet? BNE BEND ;no, then must be endpacket. 2$: CALL BICHR ;input next. MOV R1,(R2)+ ;store data in memory buff. .if NE,CKS ADD R1,R5 ;Update ADC R5 ; checksum .endc SOB R4,2$ ; CALL BICHR ;checksum! CMP R1,R5 ;O.K.? BNE BFATAL ;no, then branch. BR BRDPKT ;and again. BEND: CALL BICHR ;Receive Endpacket MOV R3,R2 ;Save succescode. 1$: .if NE,CKS ADD R1,R5 ;and ADC R5 ; receive .endc CALL BICHR ; rest SOB R4,1$ ; of ; End- CMP R1,R5 ; packet. BNE BFATAL ;checksum O.K.? TSTB R2 ;check succes code. BMI BFATAL ;Succes or error? MOV UNITNR,R0 ;Give unitnr. to handler's bootstrap. .IF EQ,TEST CLR PC ;Start executing block just read .IFF BIS #100,@#RCSR .EXIT .ENDC ;TEST .IF EQ,WB BICHR: TST (R0) ;Input ready bit = highest bit! BPL BICHR MOV 4(R0),R1 ;R0 points to status reg.: .IFF BICHR: TSTB -4(R0) ;Input status WB BPL BICHR MOV -2(R0),R1 .ENDC ;WB MOV R1,R3 ;COPY, lowbyte R3=packet word cnt. SWAB R3 ; 2 = PD$CSR+2 = output buffer RETURN ; 4 = PD$CSR+4 = input buffer BCHROS: MOV R3,2(R0) 1$: TSTB (R0) ;Output ready bit = No. 7 !! BPL 1$ RETURN .ENDC ;INT-2 .IF EQ,INT-3 ;-------------------------------QNBOOT--------------------------------; GO=1 SND=2 CE=4 PD$CSR=172410 MOV (PC)+,R0 BOOCSR: .WORD PD$CSR+4 ;Command and status reg. CLR @R0 WAIT: TSTB @R0 ;Output ready? BPL WAIT ; R5 = buffer address for input/output ; R4 = address checksum/pattern ; R3 = wordcount ; Send command packet. ; ==================== MOV #B$PKT,R5 ;Point to packet flag MOV #B$CHK,R4 ;Point to checksum. CALL BTOUT1 ;Send flag=initial checksum! MOV (R5)+,@R4 ;Init=clear checksum. MOV #R$MSIZ,R3 CALL BTOUT ;Send command pkt contents. .if NE,CKS 1$: ADD (R5)+,@R4 ;update ADC @R4 ; checksum. SOB R3,1$ ;no .iff MOV #CHECK,@R4 MOV @R4,@R5 .endc ;CKS CALL BTOUT1 ;send checksum/pattern MOV #B$PKT,R5 ;Point to packet flag ; Receive bootstrap data and store them. BRDPKT: CALL BTINP1 ;R1 contains receiv. word. .iif NE,CKS MOV @R5,@R4 ;So init chks, R4->B$CHK CMPB R1,#R$DATA ;data packet? BNE BEND ;no, then must be endpacket. SWAB R1 MOV #R$DSIZ,R3 ;Full pkt. TSTB R1 ;O.K. BEQ 3$ ;Yes, then go. CLR R3 ;No. BISB R1,R3 ;R3 = packetwordcnt. 3$: MOV R2,R5 ;Copy buffer address ADD R3,R2 ;Update buff. address. ADD R3,R2 CALL BTINP CALL CHKINP BR BRDPKT ;and again. BEND: .iif NE,CKS MOV (R5)+,@R4 ;Init checksum, R5 points to B$OPC MOV #R$MSIZ,R3 CALL BTINP ;Receive Endpacket TST R1 ;Succescode(neg.= bit 15 up=neg. high byte) BMI BFATAL ;Succes or error? CALL CHKINP MOV UNITNR,R0 ;Give unitnr. to handler's bootstrap. .IF EQ,TEST CLR PC ;Start executing block just read .IFF BIS #100,@#RCSR .EXIT .ENDC ;TEST BTINP1: MOV #1,R3 BTINP: MOV R5,-4(R0) ;BAR NEG R3 MOV R3,-2(R0) ;WCNT NEG R3 MOV #CE+GO,(R0) CALL QNRDY MOV @R5,R1 ;R5->B$CHK/B$FLG, R4->B$CHK, /Save succescode. CMP R3,#1 BEQ QNRET .if NE,CKS 2$: ADD (R5)+,@R4 ;Update ADC @R4 ; checksum SOB R3,2$ .endc ;CKS QNRET: RETURN CHKINP: MOV #B$PKT,R5 ;Point to packet flag CALL BTINP1 ;checksum! CMP @R5,@R4 ;O.K.? BNE BFATAL ;no, then branch. RETURN BTOUT1: MOV #1,R3 BTOUT: MOV R5,-4(R0) ;BAR NEG R3 MOV R3,-2(R0) ;WCNT NEG R3 MOV #SND+CE+GO,(R0) QNRDY: TSTB (R0) ;Output/Input ready bit = No. 7 !! BPL QNRDY TST (R0) ;Error? BMI BFATAL RETURN ;---------------------------- END QNBOOT------------------------------; .ENDC ;INT-3 BFATAL: DEC RTRCNT BNE BRESTR MOV #ERRTXT,R1 CALL PUTSTR .IF NE,TEST BIS #100,@#RCSR .EXIT .IFF ERSTOP::HALT .ENDC ;TEST B$PKT:: .BYTE 2,5 B$OPC: .BYTE 2,0 B$UNT: .WORD 0,0 B$WCNT: .WORD 0 B$BLK: .WORD 0 B$CHK: .WORD 0 RTRCNT: .WORD 0 UNITNR: .WORD 0 ;------------------------miscellaneous subroutines----------------------; PUTCHR: TSTB @#XCSR ;Print character (in R0) BPL PUTCHR MOVB R0,@#XDBR RET: RETURN PUTSTR: MOVB (R1)+,R0 ;Print string (pointer in R1) BEQ CRLF CMPB #200,R0 BEQ RET CALL PUTCHR BR PUTSTR CRLF: MOV #15,R0 CALL PUTCHR MOV #12,R0 CALL PUTCHR RETURN GETCHR: TSTB @#RCSR ;Get character from keyboard (put in R0) BPL GETCHR MOVB @#RDBR,R0 BIC #177600,R0 RETURN GETNMB: CLR R1 ;Get number (assemble in R1) 1$: CALL GETCHR CMP R0,#15 BEQ CRLF CALL PUTCHR BIC #177600,R0 SUB #60,R0 ASL R1 ;*2 MOV R1,-(SP) ASL R1 ;*4 ASL R1 ;*8 ADD (SP)+,R1 ;*2+*8 = *10. ADD R0,R1 BR 1$ GETPAS: MOV #NPASSW,R5 MOV #PATTRN,R4 MOV #PASWRD,R3 MOV @#RDBR,R0 ;Dump input register. CLRB PASFLG NEXTC: CALL GETCHR ;Get PASSWORD, no echo. CMP R0,#15 ;RETURN? BEQ INDONE 1$: MOVB (R4)+,R2 ADD R2,R0 ;Scramble input char. CMPB R0,(R3)+ ;Match? BEQ 2$ INCB PASFLG 2$: DEC R5 BR NEXTC INDONE: TSTB PASFLG BNE NOTOK TST R5 BNE NOTOK PASOK: CALL CRLF CLC RETURN NOTOK: SEC RETURN PASTXT: .BYTE 15,12 .IIF EQ,INT-1 .ASCII /DR/ .IIF EQ,INT-2 .ASCII /WB/ .IIF EQ,INT-3 .ASCII /QN/ .IF EQ,CKS .ASCII /BOOT-NCK, PASSWORD>/<200> .IFF .ASCII /BOOT-CKS, PASSWORD>/<200> .ENDC; CKS NMBTXT: .ASCII /Dev.no. (0-7) [0]>/<200> ERRTXT: .ASCIZ /BT-Err/ PASWRD: .BYTE 'N+1,'K-4,'G+7,'.-11. ;Password set here! (Set to "NKG.") PATTRN: .BYTE 1,-4,7,-11. ;Scrambling numbers; one for each PASFLG: .BYTE 0 ; password character, should also be .EVEN ; added to the corresponding character .IIF NE,TEST BUFFER: .BLKW 256. .END BOOT