.TITLE FRUN RT-11 RELOCATING LOADER .NLIST BEX .ENABL LC ; ; Pdp11/dcn basic operating system - rt-11 relocating loader ; ; This program reads an rt-11 foreground program file (.rel extension) and ; loads it into the user area allocated to this process. It also sets the ; initial starting address (loc 40), intiial stack address (loc 42) and ; highest program address (loc 50) in the cache area. Note: this program only ; works with rt-11 version 3 or later files. ; ; System definitions ; .ASECT .MCALL .COM ;dcn macros .MCALL .EXIT,.GTJB,.PRINT,.CSISP,.LOOKU ;rt-11 macros .MCALL .ENTER,.READW,.WRITW,.PURGE .COM ; ; Module definitions ; ; Control information for rt-11 linker ; . = 44 .WORD 2000 ;position independent .PAGE ; ; Procedure segment ; .PSECT $BOS ;(stack extends downwards) ; ; Frun - relocating loader ; FRUN: MOV PC,R3 ;initialize buffer pointer ADD #BUFFER-.,R3 MOV PC,R4 ;initialize arg area pointer ADD #AREA-.,R4 MOV PC,R5 ;initialize aux arg area pointer ADD #AUXBLK-.,R5 .GTJB R4,R3 ;get job parameters MOV 4(R3),R1 ;(relocation factor) MOV 22(R3),FILNAM+2 ;(rad50 process name) MOV R1,RELFAC BNE 2$ ;branch if foreground ADD #600,RELFAC ;(this makes virtual=real) ADD #500,R1 2$: ADD #12,R1 ;point to argument string MOV PC,R2 ;get file specs ADD #DEFTYP-.,R2 .CSISP R3,R2,R1 BCS 1$ ;branch if error .PURGE #3 ;find file .PURGE #17 MOV R3,R1 ADD #30.,R1 .LOOKU R4,#3,R1 BCC LDR56 ;branch if no error MOV PC,R0 ;file not found ADD #COM3-.,R0 BR LDR25 ; 1$: .EXIT ; LDR56: .READW R5,#3,R3,#256.,#0. ;read control block BCC LDR23 ;branch if no error JMP LDR21 ; LDR23: CMP 60(R3),DEFTYP ;is this really a .rel file BEQ 4$ ;branch if yes MOV PC,R0 ;bad file format ADD #COM5-.,R0 BR LDR25 ; 4$: MOV RELFAC,R1 ;get relocation factor SUB 42(R3),R1 ;compute relocation factor ADD 54(R3),R1 ;adjust for requested stack space MOV R1,RELFAC MOV 50(R3),R0 ;compute program break ADD R1,R0 ADD #100,R0 ;(allow for stack fidget) CMP R0,SP ;will it fit BLO LDR57 ;branch if yes MOV PC,R0 ;program too large ADD #COM4-.,R0 LDR25: JMP LDR20 ; LDR57: MOV 34(R3),@#34 ;initialize trap vector BEQ 2$ ADD R1,@#34 2$: MOV 36(R3),@#36 MOV 40(R3),@#40 ;initialize start address ADD R1,@#40 MOV 42(R3),@#42 ;initialize stack address ADD R1,@#42 MOV 44(R3),@#44 ;initialize job control word MOV 46(R3),@#46 ;initialize usr address BEQ 1$ ;branch if not given ADD R1,@#46 1$: MOV 50(R3),@#50 ;initialize highest address ADD R1,@#50 CLR @#52 ;initialize error indicators ; ; Read root segment and open overlay file (if necessary) ; ADD 42(R3),R1 MOV 52(R3),R2 ;get size of program INC R2 CLC ;in words ROR R2 MOV 56(R3),SEGLNG ;set overlay switch MOV 62(R3),2(R5) ;set for relocation block .READW R4,#3,R1,R2,#1. ;read root segment BCS LDR21 ;branch if error TST SEGLNG ;is this overlay structure BEQ 3$ ;branch if no MOV PC,R2 ;yes. open overlay file ADD #FILNAM-.,R2 .ENTER R3,#17,R2,2(R5) BCS LDR11 ;can't do that MOV @#42,R2 ;establish segment table pointer MOV 14(R2),R2 ADD #6,R2 ADD RELFAC,R2 MOV R2,SEGPTR ; ; Relocate text and construct overlay file (if necessary) ; 3$: CLR R2 LDR13: JSR PC,GETREL ;get next relocation word CMP R0,#177777 ;is this end of segment BEQ LDR18 ;branch if yes CMP R0,#177776 ;no. is this end of relocation info BEQ LDR14 ;branch if yes ASL R0 ;no. compute word address ADD 4(R4),R0 MOV R0,-(SP) ;save real address JSR PC,GETREL ;get offset word ADD RELFAC,R0 ;relocate MOV R0,@(SP)+ ;store BR LDR13 ; LDR18: JSR PC,GETREL ;end of segment. get next reloc seg number MOV R0,-(SP) JSR PC,GETREL ;discard word count MOV (SP)+,R0 CMP R0,OVRBLK ;is this segment to be relocated BEQ LDR13 ;branch if yes MOV R0,OVRBLK 1$: .WRITW R4,#17 ;write out relocated segment BCS LDR11 ;branch on i/o error MOV SEGPTR,R0 ;get next segment MOV (R0)+,4(R4) MOV (R0)+,2(R4) MOV (R0)+,6(R4) MOV R0,SEGPTR .READW R4,#3 BCS LDR21 ;branch if error CMP 2(R4),OVRBLK ;is this segment to be relocated BLO 1$ ;branch if no BR LDR13 ; LDR21: MOV PC,R0 ;input error ADD #COM1-.,R0 BR LDR20 ; LDR11: MOV PC,R0 ;output error ADD #COM2-.,R0 LDR20: .PRINT .PURGE #3 ;error. don't let files get closed .PURGE #17 .EXIT ; ; End of relocation info. clean up and start prog ; LDR14: TST SEGLNG ;is this overlay file BEQ LDR17 ;branch if no MOV SEGPTR,R1 ;yes. get table pointer 1$: .WRITW R4,#17 ;write last segment BCS LDR11 ;branch if i/o error CMP @R1,#4537 ;*** zilch *** is this end of table BEQ LDR17 ;branch if yes MOV (R1)+,4(R4) ;no. get next segment MOV (R1)+,2(R4) MOV (R1)+,6(R4) .READW R4,#3 BCS LDR21 ;branch if error BR 1$ ; LDR17: .PURGE #3 ;discard load file (keep overlay file) MOV @#40,R0 ;is start address valid BIT #1,R0 BNE 1$ ;branch if no MOV @#42,SP ;yes. load sp JMP @R0 ;bonzai!! ; 1$: MOV PC,R0 ;invalid start address ADD #COM6-.,R0 BR LDR20 ; ; Subroutine to read next relocation word ; GETREL: TST R2 ;is this end of buffer BNE 1$ ;branch if no .READW R5 ;read next relocation block BCS LDR21 ;branch if error INC 2(R5) ;increment block number MOV R3,R1 ;set up for list MOV #256.,R2 1$: MOV (R1)+,R0 ;get next word number DEC R2 RTS PC .PAGE ; ; Data segment ; ; Read-only data ; DEFTYP: .RAD50 'REL ' ;input files *.rel COM3: .ASCIZ '?FRUN-F-File not found' COM1: .ASCIZ '?FRUN-F-Input error' COM5: .ASCIZ '?FRUN-F-Bad file format' COM4: .ASCIZ '?FRUN-F-Program too large' COM2: .ASCIZ '?FRUN-F-Output error' COM6: .ASCIZ '?FRUN-F-Invalid start address' .EVEN ; ; Read/write data ; BUFFER: .BLKW 256. ;(r3) buffer AREA: .BLKW 5 ;(r4) argument block AUXBLK: .BLKW 5 ;(r5) auxilliary argument block FILNAM: .RAD50 'DK SWP' ;(r2) overlay file name RELFAC: .BLKW 1 ;relocation factor OVRBLK: .BLKW 1 ;current overlay block number SEGLNG: .BLKW 1 ;length of overlay segment (switch) SEGPTR: .BLKW 1 ;overlay segment table pointer ; .END FRUN