.MCALL .MODULE .MODULE DUPWBT,VERSION=10,COMMENT=,IDENT=NO ; 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. ; Edit History: ; ; 001 11-Jan-80 02:58 Guldenschuh, Chuck cpg [240,148] ; Correct output filename problem ; QAR N11-03126(B24) ; (001) ; 002 28-Jan-80 10:59 Guldenschuh, Chuck cpg [240,148] ; Correct "Volume not RT-11 format" problem ; (002) ; 010 06-Nov-1990 JFW ; bracket error messages with ;+/;ERROR/.../;- .ENABL LC,GBL .IIF EQ MDUP,.MCALL .CSTAT .SBTTL Symbolic definitions .IIF NDF MDUP, MDUP = 0 ;Default to no MDUP .IIF NDF M$UPD, M$UPD = 0 ;Default to no MDUP Update .IIF NDF SDC, SDC = 0 ;Default to no SDCOPY B$DEVN = 4716-1000 ;Offset to secondary boot handler filename B$FNAM = 4724-1000 ;Offset to secondary boot monitor filename B$READ = 4730-1000 ;Offset to secondary boot -> primary read HND.OP = 60 ;Offset to handler options word SYG.XM = 2 ;Bit indicating XM in handler options word .SBTTL PSECT definitions PSECT IMPURO ;002 PSECT WBOOT ;Code psect ;**-1 PSECT PATCH ;Patch psect .BLKW 32. PSECT IMPURO ;***** CRITICAL ORDERING ***** MON.OP: .WORD 0 ;Monitor sysgen option word BOTPTR: .WORD 0 ;-> primary bootstrap in handler BOTSIZ: .WORD 0 ;Size of primary boot in bytes BOTRED: .WORD 0 ;-> primary bootstrap read routine ;***** END CRITICAL ORDERING ***** .SBTTL WBOOT - Write bootstrap ;+ ; WBOOT ;- ORIGIN WBOOT WBOOT:: .IF EQ MDUP .IFTF ;EQ MDUP 1$: CLR -(SP) ;Assume a reasonable sized machine .IFF ;EQ MDUP MOV IBFBEG,R0 ;R0 -> I/O buffer .IFT ;EQ MDUP .GTCOR #<512.*6> ;Try for the max memory we need BCC 3$ ;Branch if we got it .GTCOR #<512.*2> ;Try for the minimum amount BCC 2$ ;Branch if we got it ;+ ;ERROR .ERR #ERAREA,#FE.NOM,LEVEL=FATAL,RETURN=NO ; <-F-Insufficient memory> ;- 2$: INC @SP ;Remember that we have a small machine 3$: MOV R0,IBFBEG ;Save the start of the buffer .ENDC ;EQ MDUP MOV R0,R5 ;Save the buffer pointer WAIT #WAITIN,#OUTFIL ;Wait for the device to be mounted MOV R5,$DIRBF ;Set up the directory buffer MOV #ICHAN,$DIRCH ;Set up the directory channel MOV #INFILE,R3 ;R3 -> monitor file name MOV #<^RSYS>,6(R3) ;The extension is .SYS MOV #10.,R4 ; # OF CHARS TO CHECK IN FILE SPEC MOV R0,-(SP) ; SAVE R0 MOV R1,-(SP) ; SAVE R1 MOV R3,R0 ; R0 -> MONITOR FILE NAME MOV #IOAREA,R1 ; R1 -> BUFFER CALL $FNASC ; CONVERT TO ASCII MOV #IOAREA,R1 ; RESET TO BEGINNING OF BUFFER 35$: CMPB #'*,(R1) ; CHAR A '*' ? BEQ 42$ ; YES, BRANCH. ILLEGAL IN BOOT NAME CMPB #'%,(R1)+ ; CHAR A '%' ? BEQ 42$ ; YES, BRANCH. ILLEGAL IN BOOT NAME DEC R4 ; COUNT CHAR PROCESSED BGT 35$ ; BRANCH IF MORE CHARS TO PROCESS ; NOW RESTORE VALUES MOV #INFILE,R3 ; R3 -> MONITOR FILE MOV #ICHAN,R4 ;Channel to read monitor file on MOV (SP)+,R1 ; RESTORE R1 -> BUFFER MOV (SP)+,R0 ; RESTORE R0 -> FILE NAME ;+ ;ERROR CALL LOOKUP ;"Lookup" the file BCC 5$ ;Branch if we found it 4$: MOV R0,-(SP) ;Copy the error code MOV #INFILE,R0 ; R0 = RAD50 FILENAME 41$: MOV #IOAREA,R1 ; R1-> BUFFER AREA CALL $FNASC ; CONVERT RAD50 TO ASCII ; MOV R1,R3 ; R3=ASCII FILENAME MOVB #0,(R1) ; PUT SO NO GARBAGE GETS PRINTED MOV (SP)+,R1 ; RESTORE R1 .ERR #ERAREA,R1,LEVEL=FATAL,RETURN=NO,ASCII=#IOAREA ; <-F-File not found dev:filename> ;- 42$: MOV (SP)+,R1 ; RESTORE R1 -> BUFFER MOV (SP)+,R0 ; RESTORE R0 -> FILE NAME ;+ ;ERROR .ERR #ERAREA,#ILC,LEVEL=FATAL,RETURN=NO ; <-F-Invalid command> ;- 5$: MOV #4,R4 ;Block number to read if MINMEM <> 0 MOV #1,R3 ;Number of blocks to read if MINMEM <> 0 TST @SP ;Minimum sized buffer? BNE 6$ ;Branch if so ADD #<512.*2>,R5 ;Skip directory, primary boot buffers MOV R4,-(SP) ;Swap MOV R3,R4 ; number of blocks MOV (SP)+,R3 ; with block number 6$: SWAB R3 ;Make number of blocks number of words READ #IOAREA,#ICHAN,R5,R3,R4 ;Read in secondary boot BCC 9$ ;Branch if no error ;+ ;ERROR 7$: MOV #FE.INE,R0 ;Set up the code 8$: MOV #INFILE,R3 ;And the filename pointer JMP 4$ ;Give the error ; <-F-Input error dev:filename> ;- 9$: ASL R3 ;Make R3 a byte count ADD R5,R3 ;R3 -> past end of buffer MOV -(R3),MON.OP ;Save monitor SYSGEN options. R3 -> to it MOV #OUTFIL+2,R1 ;R1 -> output file spec MOV BOOWHO,@R1 ;Get user specified name BNE 10$ ;Branch if there .IF EQ MDUP .CSTAT #IOAREA,#OCHAN,#CSTAT ; Get status on the device MOV CSTAT+12,@R1 ; Assume 2 letter device name already CMP #7,CSTAT+10 ; Is the unit number greater than 7? BHIS 10$ ; Branch if not ;+ ; Get pointer to $PNAM2 and offset to $PNAME ;- MOV R3,-(SP) ; Save non-volitale registers MOV R4,-(SP) MOV R5,-(SP) MOV @#S$RMON,R5 ; R5 -> RMON MOV S.PNAM(R5),R4 ; R4 = offset from RMON to $PNAME. ADD R5,R4 ; R4 -> $PNAME MOV R4,R3 ; R3 -> $PNAME ; Calculate $SLOT*4 by searching for -1 at end of $ENTRY table 91$: CMP (R3)+,#-1 ; Search for end of $ENTRY table. BNE 91$ ; Keep going TST -(R3) ; R3 -> end of $ENTRY table SUB R4,R3 ; R3 = bytes in combined tables ; R3 now contains the value $SLOT*4; the size of 2 tables MOV R3,R0 ; Save $SLOT*4 value ASL R3 ; Calculate offset from $PNAME ADD R0,R3 ; to $PNAM2 $SLOT*4 * 3 TST (R3)+ ; + 2 for -1 at end of $ENTRY table ADD R3,R4 ; R4 -> $PNAM2 ;+ ; Find device name in $PNAM2 - must be there since unit # greater than 7 ;- 92$: CMP CSTAT+12,(R4)+ ; Is this the entry? BNE 92$ ; Branch if not, loop till found ;+ ; Get 2 letter device name from corresponding entry in $PNAME ;- SUB R3,R4 ; R4 -> entry in $PNAME + 2 MOV -(R4),@R1 ; Get 2 letter device name MOV (SP)+,R5 ; Restore non-volitale registers MOV (SP)+,R4 MOV (SP)+,R3 ;+ ; Open the device handler file ;- .IFF ;EQ MDUP ; 8 unit only code for MDUP MOV -2(R1),@R1 ;Else copy the device name MOV @R1,R0 ;R0 = physical device name of output device MOV R1,-(SP) ;Save R1 MOV #50,R1 ;Get the unit number of the output device CALL $DIV ; by dividing by 50(8) MOV R1,R0 ;Copy the remainder MOV (SP)+,R1 ;Restore R1 SUB R0,@R1 ;Get rid of the unit number .ENDC ;EQ MDUP 10$: ADD -2(R3),@R1 ;Add in the handler suffix ;CG14 CLR 2(R1) ;Get rid of whats left of the filename ;001 MOV #<^RSYS>,4(R1) ;Filetype is .SYS MOV #OCHAN,$DIRCH ;Set up the directory channel MOV #OCHAN,R4 ;R4 = output channel number MOV #OUTFIL,R3 ;R3 -> system device handler name ;+ ;ERROR CALL LOOKUP ;"Lookup" the file BCC 11$ ;Branch if found MOV R0,-(SP) ; SAVE ERROR CODE MOV #OUTFIL,R0 ; R0-> FILESPEC JMP 41$ ; GO GIVE ERROR MESSAGE ;- 11$: MOV IBFBEG,R5 ;R5 -> start of our buffer space READ #IOAREA,#OCHAN,R5,#512.,#0 ;Read in the handler BCC 13$ ;Branch if no error ;+ ;ERROR 12$: MOV #FE.INE,R0 ;Set up the error code JMP 4$ ;Go give the error ; <-F-Input error dev:filename> ;- 13$: ADD #HND.OP,R5 ;R5 -> handler SYSGEN option word MOV #MON.OP,R3 ;R3 -> monitor SYSGEN option word CMP (R5)+,(R3)+ ;Handler and monitor options match? BEQ 14$ ;Branch if so ;+ ;ERROR .ERR #ERAREA,#CSO,LEVEL=FATAL,RETURN=NO ; <-F-Conflicting SYSGEN options> ;- 14$: MOV (R5)+,(R3)+ ;Save -> primary bootstrap BNE 18$ ;Branch if it's there ;+ ;ERROR MOV #NBF,R0 ; and the error code 15$: MOV #OUTFIL,R3 ;Set up the filename pointer 16$: JMP 4$ ;Go give the error ; <-F-Non-bootable file dev:filename> 17$: BR 7$ ; ; <-F-Input error dev:filename> ;- 18$: MOV (R5)+,(R3)+ ;Save primary boot size (bytes) MOV @R5,@R3 ;Save -> primary boot read routine MOV -(R3),R4 ;R4 = primary boot size ASR R4 ;Make it words MOV R4,-(SP) ;Save it for later MOV -(R3),R1 ;R1 -> primary boot code in handler ASR R1 ;Make it a word offset CLR R2 ;MOVB with no sign extend BISB R1,R2 ;R2 = word offset from start of block to boot ADD R2,R4 ;Bump the number of words to read ASL R2 ;Make word offset a byte offset CLRB R1 ;High byte is block number of boot SWAB R1 ;Get block number in low byte MOV IBFBEG,R5 ;R5 -> start of input buffer MOV #OUTFIL,R3 ;R3 -> handler filename READ #IOAREA,#OCHAN,R5,R4,R1 ;Read in the boot ;+ ;ERROR BCS 12$ ;Branch on error ; <-F-Input error dev:filename> ;- ADD R2,R5 ;R5 -> start of primary boot MOV (SP)+,R2 ;R2 = size of boot in words MOV #OCHAN,R4 ;R4 = output channel number CALL PURGE ;Make channel non-file-structured again ;+ ;ERROR BCS 16$ ;Oops! ; <-F-System error> ;- MOV 2(R3),MON.OP ;Save the filename CLR 2(R3) ;But forget it for error messages CLR 6(R3) ; WRITE #IOAREA,#OCHAN,R5,R2,#0 ;Write out the primary bootstrap BCC 20$ ;Branch if no error ;+ ;ERROR 19$: MOV #FE.OPE,R0 ;Set up error code BR 15$ ;Go give error ; <-F-Output error dev:> ;- 20$: MOV IBFBEG,R5 ;R5 -> start of buffer space MOV #2,R4 ;R4 = output block number MOV R5,R3 ;R3 -> start of buffer space MOV #<256.*4>,R2 ;R2 = number of words to write TST (SP)+ ;Minimum memory configuration? BEQ 21$ ;Branch if not ASR R2 ;Buffer is only half size READ #IOAREA,#ICHAN,R3,R2,#1 ;Read in first half of secondary boot BCS 17$ ;Branch on error ;+ ;ERROR ; <-F-Input error dev:filename> WRITE #IOAREA,#OCHAN,R3,R2,R4 ;Write it out to the disk BCS 19$ ;Branch on error ; <-F-Output error dev:> READ #IOAREA,#ICHAN,R3,R2,#3 ;Read in second half of secondary boot BCS 17$ ;Branch on error ; <-F-Input error dev:filename> ;- SUB #<512.*2>,R5 ;Fix R5 for common code ADD #2,R4 ;Bump the output block number BR 22$ ;Merge with common code 21$: ADD #<512.*2>,R5 ;Skip past primary boot buffer MOV R5,R3 ;R3 -> output buffer 22$: MOV MON.OP,B$DEVN(R5) ;Save the device name MOV INFILE+2,B$FNAM(R5) ;Save the monitor filename MOV INFILE+4,B$FNAME+2(R5) ;Both words of it MOV BOTRED,B$READ(R5) ;Save the pointer to primary read routine WRITE #IOAREA,#OCHAN,R3,R2,R4 ;Write out secondary boot ;+ ;ERROR BCS 19$ ;Branch on error ; <-F-Output error dev:> ;- RETURN .END