!%EXTERNALINTEGERFNSPEC SMADDR(%INTEGER CHAN,%INTEGERNAME LEN) !%EXTERNALROUTINESPEC CLOSESM(%INTEGER CHAN) %EXTERNALROUTINESPEC PROMPT(%STRING(15) S) %begin %OWNINTEGER CHECKSUM %OWNBYTEINTEGERARRAY STORE(-40:K'177777') %OWNINTEGER BASE=0 %OWNINTEGER RA,SA,FA %OWNSTRING(255) ST %OWNINTEGER I,J,HIGH ADDRESS,START ADDRESS,COMMAND,CH,X %ROUTINE WRITE OCTAL(%INTEGER NO) !================================= %INTEGER I NO=NO&K'177777' %CYCLE I=15,-3,0 PRINTSYMBOL((NO>>I)&7+'0') %REPEAT %END %routine put(%integer ch) print ch(ch) checksum=checksum+ch %end %ROUTINE DUMP(%INTEGER BOTTOM,TOP) !======================================= ! This routine dumps a DEC PDP11 loader format ! file. %INTEGER ADDR,SIZE,I select output(6) %if bottom<-40 %or top > k'177776' %or bottom > top %start select output(0) printstring("Dump disaster") newline %monitor %stop %finish ADDR=BOTTOM size = top-addr+1 %CYCLE I=1,1,2; PRINT CH(0); %REPEAT CHECKSUM=0 ! Do header PUT(1); PUT(0) ! Do size PUT((SIZE+6)&K'377'); PUT((SIZE+6)>>8) ! Do address %if addr=-40 %then i=0 %else i=addr PUT(i&K'377'); PUT(i>>8) ! Now do DATA %CYCLE I=1,1,SIZE PUT(STORE(ADDR)) ADDR=ADDR+1 %REPEAT ! Finally put the checksum PUT((-CHECKSUM)&K'377') %END %ROUTINE LOAD !============= %OWNINTEGER ST,FIN %INTEGER SIZE,ADDR,X1,X2,I,K %INTEGER HEADER %INTEGERFN GET %INTEGER I %IF ST<=FIN %THEN I=BYTEINTEGER(ST) %AND ST=ST+1 %C %ELSE %SIGNAL %EVENT 9 CHECKSUM=CHECKSUM+I %RESULT=I %END HEADER=0 !ST=SMADDR(5,I) FIN=ST+I-1 HIGH ADDRESS=0 K=1 %CYCLE; !OVER ALLINPUT BLOCKS I=GET %UNTIL I=1 ;!SKIP TO LIKELY START %SIGNAL %EVENT 12,I %UNLESS GET=0; !CONFIRM O.K. CHECKSUM=1; !INITIALISE CHECKSUM !GET SIZE OF THIS BLOCK X1=GET; X2=GET; SIZE=X2<<8+X1-6 !GET ADDRESS OF THIS BLOCK X1=GET; X2=GET; ADDR=X2<<8+X1 %IF SIZE=0 %START; !LOAD BLOCK START ADDRESS=ADDR !CLOSESM(5) %RETURN %FINISH %IF HEADER=0 %START {First block is DEIMOS HEADER} ADDR = -40 HEADER = 1 %FINISH %WHILE SIZE>0 %CYCLE STORE(ADDR)=GET ADDR=ADDR+1 SIZE=SIZE-1 %REPEAT I=GET %SIGNAL %EVENT 13,CHECKSUM&K'377' %IF CHECKSUM&K'377'#0 HIGH ADDRESS=ADDR %IF HIGH ADDRESS= k'200000' %start %if state > 1 %start dump(b,e) %finish %exit %finish %if store(p) = 0 %then action = 0 %else action = 1 ->x(3*action+state) x(1): {found zero when skipping for non-zero; do nothing} %continue x(2): {found zero when in block, last thing was non zero} state=3 nz=1 -> check l x(3): {zero when in block, last thing was a zero} nz=nz+1 %if nz>10 %start dump (b,e) state=1 %continue %finish -> check l x(4): {first non-zero character in block} b = p; e = p state = 2 nb = 1 %continue x(5): {non-zero in block} x(6): {ditto, last thing was zero} e = p check l: nb=nb+1 %if nb=max size %start dump (b,e) state=1 %finish %repeat %end %routine dump start(%integer start) print ch(0); print ch(0) checksum=0 put(1); put(0); put(6); put(0) put(start&k'377') put(start>>8) put((-checksum)&k'377') %end %string(20) input,output load select output(6) dump(-40,-1); !dump deimos header scan dump start(start address) %endofprogram