10
20
30 :
40 DIM ctrl% 31,mem% &4100:X%=ctrl%:Y%=X%DIV256
50 ON ERROR REPORT:PROCClose_All:PRINT " at line ";ERL:END
60 ptr%=0:in%=0
70 PRINT "Enter input files, end with RETURN"
80 REPEAT:INPUT LINE ": "in$:IF in$<>"":PROCadd
90 UNTIL in$=""
100 INPUT LINE "Enter output filename: "out$
110 OSCLI "Save "+out$+" "+STR$~mem%+"+"+STR$~ptr%+" 0 FFFBBC00"
120 ON ERROR END
130 OSCLI "Stamp "+out$
140 END
150 :
160 DEFPROCadd
170 IF LEFT$(in$,1)="|":ENDPROC
180 IF LEFT$(in$,1)="*":OSCLI MID$(in$,2):ENDPROC
190 in%=OPENIN(in$):IF in%=0:PRINT"File '"in$"' not found":ENDPROC
200 len%=EXT#in%:IF len%>&4100-ptr%:PRINT"File '"in$"' too long":CLOSE#in%:in%=0:ENDPROC
210 IF ptr%:ptr%=ptr%+2
220 PROCgbpb(4,in%,mem%+ptr%,len%,0):CLOSE#in%:in%=0
230 reloc%=0:IF mem%?ptr%=0:IF (mem%?(ptr%+2) AND &80)=&80:reloc%=ptr%+(mem%!(ptr%+1) AND &3FFF)
240 IF reloc%=0:IF ptr%:PRINT"File '"in$"' not relocatable, must be first entry":ENDPROC
250 old%=ptr%:ptr%=FNlink:IF old%=ptr%:PRINT"File '"in$"' too long":ENDPROC
260 FOR A%=ptr% TO &3FFF STEP 4:mem%!A%=0:NEXT A%
270 IF old%<>0 OR ptr%<&3FFF:ENDPROC
280 REPEAT:ptr%=ptr%-1:UNTIL mem%?ptr%<>mem%?&3FFF:ptr%=ptr%+1
290 ENDPROC
300 :
310 DEFPROCbyte
320 IF count%=0:byte%=mem%?reloc%:reloc%=reloc%+1:count%=8
330 IF byte%AND1:addr%=(mem%!(here%-1)AND&3FFF)+code%:mem%?(here%-1)=addr%:mem%?here%=(addr%DIV256)+&80
340
350 byte%=byte%DIV2:count%=count%-1
360 ENDPROC
370 :
380 DEFFNlink
390 IF ptr%=0:IF reloc%=0:=len% :
400 IF ptr%=0:IF reloc%>0:=reloc% :
410 :
420
430 code% =ptr% :
440 end% =reloc% :
450 count%=0 :
460 byte% =0 :
470 IF end%>&4000:=ptr% :
480 FOR here%=code% TO end%-1
490 IF (mem%?here% AND &C0)=&80:PROCbyte
500 NEXT here%
510 :
520
530
540
550
560 link%=-2
570 REPEAT
580 found%=FALSE
590 IF mem%?link%=&20 AND (mem%!(link%+3) AND &FFFFFF)=&4CF4A6:found%=TRUE:next%=link%+6
600 IF (mem%!link% AND &FF0000FF)=&4C000020:found%=TRUE:next%=link%+4
610 IF link%<0:found%=TRUE:next%=link%+6
620 IF found%:last%=link%:link%=mem%!next% AND &3FFF
630 UNTIL found%=0
640
650
660
670 :
680
690 mem%?(ptr%-2)=&20
700 mem%?(ptr%-1)=link%
710 mem%?(ptr%-0)=(link% DIV 256) OR &80
720 mem%?(ptr%+1)=&A6
730 mem%?(ptr%+2)=&F4
740 :
750
760 mem%?(next%+0)=ptr%-2
770 mem%?(next%+1)=((ptr%-2) DIV 256) OR &80
780 =end%
790 :
800 DEFPROCClose_All
810 in%=in%:IFin%:A%=in%:in%=0:CLOSE#A%
820 ENDPROC
830 :
840 DEFPROCgbpb(A%,chn%,addr%,num%,ptr%)
850 ?X%=chn%:X%!1=addr%:X%!5=num%:X%!9=ptr%:IFPAGE<&FFFFF:CALL&FFD1:ENDPROC
860 IFA%=1ORA%=3:PTR#?X%=X%!9
870 REPEAT:IFA%=1ORA%=2:BPUT#?X%,?X%!1 ELSE IFA%=3ORA%=4:?X%!1=BGET#?X%
880 X%!1=X%!1+1:X%!5=X%!5-1:UNTIL(EOF#?X%ANDA%>2)ORX%!5<1:ENDPROC