.TITLE TNLSI Load DEC Absolute Loader .NLIST BEX .ENABL LC ; ; This program transmits a copy of the DEC Absolute Loader in funny-format ; to a remote LSI-11 machine. The remote machine is left in the loader for ; subsequent loading of the program in ".LDA" format. ; ; External symbols ; .GLOBL FLAGS,ESCAPE,SFLFCB ; ; Entry symbols ; .GLOBL TNLSI ; ; System definitions ; .ASECT .MCALL .COM,.CHR ;dcnlib definitions .MCALL .MSG ;dcnlib macros .MCALL .TTYIN ;RT-11 macros .MCALL DFFCB,FORMAT ;netlib definitions .COM ;common definitions .CHR ;ascii character codes DFFCB ;define file control block ; ; Module definitions ; ; Assembly parameters ; ABSLOD = 1000 ;load address LODREG = 177560 ;default device register pointer ; ; Status bits (flags) ; SFLBIT = 100000 ;send file open bit ; ; Procedure segment ; .PSECT $BOSI,RO,I ; TNLSI: MOV R1,-(SP) ;preserve registers MOV R2,-(SP) .MSG <#^RTT > ;message to user terminal MOV R0,-(SP) FORMAT #COM10 ;loading begins .MSG (SP)+ FORMAT #COM32,#ABSADR ;send load address MOV #BSTBGN,R1 1$: MOV #<' >,R0 ;wait for odt response JSR PC,CHECK BCS 5$ ;branch if abort CMP R1,#BSTEND-2 ;is loading complete BHIS 2$ ;branch if yes FORMAT #COM33,R1 ;no. send next word TST (R1)+ BR 1$ ; 2$: FORMAT #COM34,R1 ;send final word MOV #PROG,R2 3$: MOV (R2)+,R0 ;wait for odt response JSR PC,CHECK BCS 5$ ;branch if abort MOV (R2)+,R0 ;is this end BEQ 4$ ;branch if yes MOV (R2)+,R1 ;no. send next string FORMAT R0,R1 BR 3$ ; 4$: .MSG <#^RTT > ;message to user terminal MOV R0,-(SP) BIS #SFLBIT,FLAGS ;enable file transfer FORMAT #COM41,#SFLFCB ;transfer begins [file] BR 6$ ; 5$: .MSG <#^RTT > ;message to user terminal MOV R0,-(SP) FORMAT #COM41X ;transfer suspended 6$: .MSG (SP)+ MOV (SP)+,R2 ;restore registers MOV (SP)+,R1 RTS PC ; ; Subroutine to wait for odt response ; R0 = response char ; CHECK: MOV R0,-(SP) ;save for later 1$: .TTYIN ;wait for odt response BIC #^C177,R0 CMPB R0,ESCAPE ;is this abort BEQ 2$ ;branch if yes CMPB R0,@SP ;no. is this end of odt response string BNE 1$ ;branch if no CLC ;normal exit MOV (SP)+,R0 RTS PC ; 2$: SEC ;abort exit MOV (SP)+,R0 RTS PC ; ; Data segment ; .PSECT $BOSD,RO,D ; ; Bit string consisting of absolute loader and relocation routine ; BSTBGN = . ;beginning of bootstrap ; L.CKSM = R0 L.ADR = R1 L.BC = R2 L.BYT = R3 L.PTR = R5 ; ; Start of loader ; L.LD1: MOV PC,SP ;set up stack CMP -(SP),-(SP) ; to start at l.ld1-2 MOV PC,L.PTR ;get relocated ADD #L.READ-.,L.PTR ; start address of read routine CLR L.ADR ;clear the road address L.LD1B: MOV (PC)+,(SP) ;pick up the content of L.SR: .WORD 0 ;the software switch register ROR @SP ;check relocation factor BCS L.LD1C ;jump if some relocation needed CLR @SP ;use address specified on the tape BR L.LD2 ;go do load ; L.LD1C: ASL @SP ;check for non-zero BNE L.LD2 ;jump if load address specified MOV L.ADR,@SP ;otherwise continue loading from last lo ; ; Look for the beginning of a block ; L.LD2: CLR L.CKSM ;initialize checksum JSR PC,@L.PTR ;read a frame DECB L.BYT ;check for +1 (start of a block) BNE L.LD2 ;loop until +1 is found JSR PC,@L.PTR ;read another frame ; ; Input and save byte count, if byte count is equal to 6 ; go to proceed jump ; JSR PC,L.GWRD ;get full byte count MOV R4,L.BC ; SUB #4,L.BC ;subtract 4 to make byte count correct CMP #2,L.BC ;was byte count equal to 6? BEQ L.JMP ;jump if no data (e.g. - jump block) JSR PC,L.GWRD ;get load address ADD @SP,R4 ;generate actual address MOV R4,L.ADR ;and put it into the proper cell ; ; Read in remainder of data ; If the loader halts at l.bad, a checksum error ; has occured, l.byt will contain the expected checksum, ; and r0 will contain the deviation from the expected ; checksum, ; L.LD3: JSR PC,@L.PTR ;read a frame BGE L.LD4 ;branch if more data remains TSTB L.CKSM ;if checksum is BEQ L.LD2 ;correct, then continue L.BAD: HALT ;ckecksum error BR L.LD2 ;press continue to ignore checksum ; L.LD4: MOVB L.BYT,(L.ADR)+ ;store 8 bits at a time BR L.LD3 ; the re-loop ; ; Input a frame, decrement byte count, and accumulate checksum ; L.READ: MOV L.DEV,L.BYT ;device address to l.byt INCB @L.BYT ;select reader L.R1: TSTB @L.BYT ;done ? BPL L.R1 ;no MOVB 2(L.BYT),L.BYT ;get character ADD L.BYT,L.CKSM ;add to checksum BIC #177400,L.BYT ;mask off junk DEC L.BC ;decrement byte count by one RTS PC ; ; Assemble one full word of data ; L.GWRD: MOV (SP)+,L.TMP ;save return in tempory JSR PC,@L.PTR ;get one character MOV L.BYT,R4 ;save l.byt in temporary JSR PC,@L.PTR ;get another frame SWAB L.BYT ;place another frame BIS L.BYT,R4 ;assemble both frames into a complete wo MOV L.TMP,PC ;return ; ; Check correctness of jump address ; halt if address is odd, jump to program if address is even ; L.JMP: JSR PC,L.GWRD ;get possible transfer address JSR PC,@L.PTR ;get checksum TSTB L.CKSM ;if incorrect BNE L.BAD ; to to checksum halt address ASR R4 ;get low order bit BCC L.JMP1 ;skip if address is even HALT ;otherwise halt BR L.LD1B ;return to start of loading loop ; L.JMP1: ASL R4 ;restore register ADD @SP,R4 JMP @R4 ;jump to user ; L.TMP: .WORD 0 ;tempory to save stack space ; . = L.LD1+276 ;move to end of page ; L.DEV: .WORD LODREG ;device register pointer ; LDREND = . ;end of absolute loader ; ; Routine to relocate loader to high memory ; RELOC: MOV #ABSLOD,SP ;initialize MOV SP,R0 MOV #ABSLOD-BSTBGN+REL10,@#4 CLR @#6 MOV #020000,R1 1$: TST @R1 ;is this ram segment addressable ADD #020000,R1 ;yes. bump to next segment CMP R1,#160000 ;is this last ram segment BLO 1$ ;branch if no REL10: SUB #LDREND-BSTBGN,R1 ;yes. move down a notch MOV R1,-(SP) MOV #LDREND-BSTBGN/2,R2 ;relocate text 2$: MOV (R0)+,(R1)+ DEC R2 BNE 2$ MOV (SP)+,PC ;dive in ; BSTEND = . ;end of absolute bootstrap ; ; Other data ; PROG: .WORD CR,COM30,0,<' >,COM34,RELADR .WORD <'@>,COM31,0,<' >,COM34,PRI7 .WORD <'@>,COM35,0,<'P>,0 ABSADR: .WORD ABSLOD ;load address RELADR: .WORD ABSLOD-BSTBGN+RELOC ;initial pc PRI7: .WORD 000340 ;initial ps COM10: .ASCIZ '?TALK-I-Loading begins' COM41: .ASCIZ '?TALK-I-Transfer begins ^F''[^I'']' COM41X: .ASCIZ '?TALK-I-Transfer suspended' COM32: .ASCIZ '^K'<0>'/^+' COM30: .ASCIZ 'R7/^+' COM31: .ASCIZ 'RS/^+' COM33: .ASCIZ '^K'<0>'^+' COM34: .ASCIZ '^K'<0>'^+' COM35: .ASCIZ 'P^+' .EVEN ; .END