10 REM > MkUnix
   20 :
   30 PRINT "Make a blank PDP11 Unix disk image"
   40 INPUT "Image file:  "out$
   50 INPUT "Image size:  "fsize$:IF fsize$="":fsize$="720K"
   60 INPUT "16bit/24bit: "bitsz$:IF bitsz$="":bitsz$="16"
   70 INPUT "Disk title:  "title$:title$=LEFT$(title$,20)
   80 :
   90 bitsz%=VAL(bitsz$)
  100 fsize%=VAL(fsize$)
  110 IF INSTR(fsize$,"K"OR INSTR(fsize$,"k"):fsize%=fsize%*2
  120 VDU 11,11,11
  130 PRINT STRING$(13,CHR$9);fsize%;" blocks, ";fsize%DIV2;"K "
  140 PRINT STRING$(13,CHR$9);bitsz%;"  "
  150 PRINT '
  160 :
  170 super% =1                     :REM Superblock always block 1
  180 itable%=2                     :REM Start block of itable
  190 isize% =fsize% DIV (43+(fsize% DIV 1000)) :REM Size of itable
  200 root%  =itable%+isize%        :REM Start block of root directory
  210 cfree% =root%+1               :REM Start of disk free space
  220 :
  230 n1%    =fsize%-cfree%         :REM Number of free blocks
  240 lsize% =n1% DIV 100           :REM Number of data blocks used to hold free blocks
  250 csize% =(n1% MOD 100)+1       :REM Number of in-core free blocks
  260 lfree% =cfree%+csize%-1       :REM Start of on-disk free block list
  270 bfree% =lfree%+lsize%         :REM Start of free disk blocks
  280 dfree% =fsize%-bfree%         :REM Disk free space
  290 today% =FNswap(FNtoday)       :REM Today's date
  300 :
  310 PRINT"fsize:   ";fsize%
  320 PRINT"itable:  ";FNh0(itable%,4);" + ";FNh0(isize%,4)
  330 PRINT"root:    ";FNh0(root%  ,4)
  340 PRINT"cfree:   ";FNh0(cfree% ,4);" + ";FNh0(csize%,4)
  350 PRINT"lfree:   ";FNh0(lfree% ,4);" + ";FNh0(lsize%,4)
  360 PRINT"bfree:   ";FNh0(bfree% ,4);" - ";FNh0(fsize%-1,4)
  370 PRINT"dfree:   ";FNh0(dfree% ,4);", ";dfree%DIV2;"K"
  380 IF isize%<1:PRINT"Error: disk image too small":END
  390 IF out$="":PRINT"Bad file name":END
  400 :
  410 DIM mem% 512
  420 out%=OPENOUT(out$):IF out%=0:PRINT"Can't create '"out$"'":END
  430 ON ERROR REPORT:PROCCloseAll:PRINT:END
  440 wr%=2
  450 :
  460 PROCclr
  470 PROCgbpb(wr%,out%,mem%,512,0):REM Boot block at &0000
  480 :
  490 mem%!0=isize%
  500 mem%!2=fsize%
  510 mem%!4=csize%
  520 FOR A%=1 TO csize%
  530   mem%!(4+A%*2)=cfree%+csize%-A%
  540 NEXT A%
  550 mem%!&19C=today%:REM Creation date
  560 $(mem%+&1DC)=title$:mem%?(&1DC+LENtitle$)=0
  570 PROCgbpb(wr%,out%,mem%,512,super%*512):REM Superblock at &0001
  580 :
  590 PROCclr        :REM inode 1
  600 mem%!0=&C1FF   :REM mode =dwrxwrxwrx
  610 mem%?2=&02     :REM links=2
  620 mem%!3=&0000   :REM user=0, group=0
  630 mem%?5=&00     :REM size DIV 65536=0
  640 mem%!6=&20     :REM size=32, two directory entries
  650 mem%!8=root%   :REM first block of root directory
  660 mem%!24=today% :REM access time
  670 mem%!28=today% :REM modify time
  680 PROCgbpb(wr%,out%,mem%,512,itable%*512):REM itable at &0002
  690 :
  700 PROCclr        :REM rest of itable
  710 IF isize%>1:FOR blk%=itable%+1 TO itable%+isize%-1:PROCgbpb(wr%,out%,mem%,512,blk%*512):NEXT
  720 :
  730 mem%!00=&0001:mem%!02=&002E:REM "."
  740 mem%!16=&0001:mem%!18=&2E2E:REM ".."
  750 PROCgbpb(wr%,out%,mem%,512,root%*512):REM root directory
  760 :
  770 PROCclr        :REM core free blocks
  780 IF csize%>1:FOR blk%=cfree% TO cfree%+csize%-2:PROCgbpb(wr%,out%,mem%,512,blk%*512):NEXT
  790 :
  800 :              :REM linked free blocks
  810 FOR blk%=lfree% TO lfree%+lsize%
  820   PROCclr
  830   IF bfree%<fsize%:mem%?0=1:mem%!2=blk%+1
  840   FOR A%=2 TO 100
  850     IF bfree%<fsize%:mem%!(A%*2)=bfree%:bfree%=bfree%+1:mem%?0=mem%?0+1
  860   NEXT
  870   IF bfree%>=fsize%:mem%?2=0:mem%?3=0
  880   PROCgbpb(wr%,out%,mem%,512,blk%*512)
  890 NEXT blk%
  900 :
  910 PRINT "Enter files to import, RETURN to finish"
  920 REPEAT
  930   INPUT "Source file:    "inf$
  940   INPUT "Dest. filename: "outf$
  950   IF inf$<>"":PROCaddfile:IF in%:CLOSE#in%:in%=0
  960 UNTIL inf$=""
  970 CLOSE#out%:out%=0
  980 END
  990 :
 1000 DEFPROCaddfile
 1010 IF outf$="":outf$=inf$
 1020 IF LEFT$(outf$,1)="/":outf$=MID$(outf$,2)
 1030 in%=OPENIN(inf$):IF in%=0:PRINT"File '"inf$"' not found":ENDPROC
 1040 size%=EXT#in%:blocks%=(size%+511)DIV512
 1050 IF blocks%+1>dfree%:PRINT"File too big":ENDPROC
 1060 csd%=FNdirfind:IF csd%=0:PRINT"Couldn't create a dir entry":ENDPROC
 1070 
 1080 
 1090 ENDPROC
 1100 :
 1110 DEFFNdirfind
 1120 REM outf$="dir/dir/file"
 1130 csd%=root%
 1140 ptr%=0
 1150 A%=INSTR(outf$,"/",ptr%)
 1160 
 1170 
 1180 
 1190 =0
 1200 :
 1210 DEFPROCclr:FOR A%=0 TO 511 STEP 4:mem%!A%=0:NEXT:ENDPROC
 1220 DEFFNtoday
 1230 A$=TIME$:dy%=VALMID$(A$,5):yr%=VALMID$(A$,12):IF yr%<1970:yr%=yr%+100
 1240 mn%=INSTR("JanFebMarAprMayJunJulAugSepOctNovDec",MID$(A$,8,3))DIV3
 1250 dy%=VALMID$("000031059090120151181212243273304334",mn%*3+1,3)+dy%
 1260 IF (yr%MOD4)=0:IFmn%>1:dy%=dy%+1
 1270 =((yr%-1970)*365.25+dy%)*86400
 1280 DEFPROCCloseAll
 1290 in%=in%:IFin%:A%=in%:in%=0:CLOSE#A%
 1300 out%=out%:IFout%:A%=out%:out%=0:CLOSE#A%
 1310 ENDPROC
 1320 :
 1330 DEFFNh0(A%,N%)=RIGHT$("0000000"+STR$~A%,N%)
 1340 DEFPROCgbpb(A%,chn%,adr%,num%,ptr%):PTR#chn%=ptr%:IF num%=0:ENDPROC
 1350 REPEATBPUT#chn%,?adr%:adr%=adr%+1:num%=num%-1:UNTILnum%<1:ENDPROC
 1360 DEFFNswap(N%):DIM A%-1:A%!0=N%:A%!4=N%:=A%!2