10 REM > DisktoFile 0.02
   20 REM Copy disk to image file
   30 REM To do: update with USBtoFile code, add Pause to USB
   40 :
   50 PRINT "Copy disk to image file"
   60 max%=(HIMEM-LOMEM-1024)DIV256:fs%=0
   70 DIM ctrl% 31,data% 256*max%-1:X%=ctrl%:Y%=X%DIV256
   80 :
   90 INPUT"Source drive:       "drv%
  100 INPUT"LVFS/ADFS/DFS:      "type$:type$=CHR$(ASCLEFT$(type$,1)AND&DF)
  110 INPUT"Output image file:  "out$
  120 osw%=&72:fsn%=8:IFtype$="L":osw%=&62:fsn%=10
  130 IF type$<>"D":IFFNdisk_err(FNadfs(data%,8,drv%,0,1,fsn%,osw%),0):END
  140 size%=data%!&FC AND &FFFFFF
  150 IF type$="D":IFFNdisk_err(FNdisk(data%,&53,drv%,0,1,1,1),1):END
  160 IF type$="D":size%=data%?7+256*(data%?6 AND 3)
  170 PRINT'"(RETURN to use &";~size%;")";CHR$11;CHR$13;"Total sectors:";SPC5;:INPUT"&"A$:PRINT:IFA$<>"":size%=EVAL("&"+A$)
  180 INPUT"Pause after errors? "pause$:pause$=CHR$(ASCLEFT$(pause$,1)AND&DF)
  190 ON ERROR REPORT:PROCabort:PRINT:END
  200 :
  210 out%=OPENOUT(out$):IF out%=0:PRINT"Can't create '"out$"'":END
  220 fs%=FNfs:sect%=0
  230 REPEAT
  240   num%=max%:IF sect%+num%>size%:num%=size%-sect%
  250   num%=FNread
  260   VDU13:PRINT"Writing   ";FNh0(sect%,6);"+";FNh0(num%,2);
  270   PROCgbpb(2,out%,data%,num%*256,0)
  280   sect%=sect%+num%
  290 UNTILsect%>=size%
  300 :
  310 VDU13:PRINT"Closing";SPC14;
  320 CLOSE#out%:out%=0
  330 VDU13:PRINT"Done";SPC17
  340 END
  350 :
  360 DEFFNread
  370 try%=(type$="D"AND3):REPEAT
  380   VDU13:PRINT"Reading ";FNh0(drv%,1);":";FNh0(sect%,6);"+";FNh0(num%,2);
  390   err%=FNattempt(num%):try%=try%-1
  400 UNTIL try%<1 OR err%=0
  410 IF err%=0:=num%
  420 IF pause$="Y":PRINT"Press SPACE to continue";:A%=GET:PRINT
  430 num%=num%DIV2
  440 try%=(type$="D"AND3):REPEAT
  450   VDU13:PRINT"Reading ";FNh0(drv%,1);":";FNh0(sect%,6);"+";FNh0(num%,2);
  460   err%=FNattempt(num%):try%=try%-1
  470 UNTIL try%<1 OR err%=0
  480 IF err%=0:=num%
  490 IF pause$="Y":PRINT"Press SPACE to continue";:A%=GET:PRINT
  500 try%=(type$="D"AND3):REPEAT
  510   VDU13:PRINT"Reading ";FNh0(drv%,1);":";FNh0(sect%,6);"+01";
  520   err%=FNattempt(1):try%=try%-1
  530 UNTIL try%<1 OR err%=0
  540 =1
  550 :
  560 DEFFNattempt(num%)
  570 IF type$<>"D":err%=FNadfs(data%,8,drv%,sect%,num%,fsn%,osw%)
  580 IF type$="D" :err%=FNdisk(data%,&53,drv%,sect%DIV10,sect%MOD10,num%,1)
  590 VDU13:A%=FNdisk_err(err%,sect%)
  600 =err%
  610 :
  620 DEFPROCabort
  630 IFfs%:OSCLI"FX143,18,"+STR$fs%:fs%=0
  640 PRINT
  650 ENDPROC
  660 :
  670 REM Disk access routines
  680 REM ====================
  690 DEFFNfs:LOCALA%,E%,Y%:=(USR&FFDA)AND&FF
  700 DEFFNdisk(addr%,cmd%,drv%,trk%,sec%,num%,den%):LOCALfs%,n%
  710 fs%=FNfs:IFfs%<>4:*FX143,18,4
  720 REPEAT:n%=num%:IFsec%+n%>10:n%=10-sec%
  730   REPEAT:X%?0=drv%+den%*24+8+2*(trk%DIV80):X%!1=addr%:X%?5=3-7*(cmd%>127)
  740     X%?6=cmd%:X%?7=trk%MOD80:X%?8=sec%:X%!9=n%OR&1E20:A%=127:CALL&FFF1
  750   A%=X%?(7+X%?5):UNTILA%<>&10:addr%=addr%+n%*256:num%=num%-n%:sec%=(sec%+n%)MOD10:trk%=trk%+1
  760 UNTILA%<>0ORnum%<1:IFfs%<>4:OSCLI"FX143,18,"+STR$fs%
  770 =A%
  780 DEFFNadfs(addr%,cmd%,drv%,sect%,num%,fsn%,osw%):LOCALfs%
  790 fs%=FNfs:IFfs%<>fsn%:OSCLI"FX143,18,"+STR$fsn%
  800 X%?0=1:X%!1=addr%:X%?5=cmd%:X%?6=drv%*32+((sect%AND&1F0000)DIV65536)
  810 X%?7=((sect%AND&FF00)DIV256):X%?8=sect%:X%!9=num%:X%!11=0
  820 A%=osw%:CALL&FFF1:A%=?X%:IFfs%<>fsn%:OSCLI"FX143,18,"+STR$fs%
  830 =A%
  840 DEFFNdisk_err(A%,S%)
  850 IFA%:PRINT"Disk error ";FNh0(A%,2);" at ";FNh0(S%,6)
  860 =A%
  870 :
  880 REM I/O routines
  890 REM ============
  900 DEFFNh0(A%,N%):=RIGHT$("00000000"+STR$~A%,N%)
  910 DEFFNfx(A%,X%):LOCAL Y%:Y%=X%DIV256:=(USR&FFF4 AND &FFFF00)DIV256
  920 DEFPROCgbpb(A%,chn%,addr%,num%,ptr%):?X%=chn%:X%!1=addr%:X%!5=num%:X%!9=ptr%:CALL&FFD1:ENDPROC