10
20
30
40
50
60
70
80
81
90 :
100 IFFNfx(0,1)<6:IFFNfx(130,0)=&FFFF ELSE PRINT"Must run on BBC I/O processor":END
110 PRINT "Copy disk to USB as a disk image"
120 PRINT "Equivalent to: *EXPORT -X<drv> usbfile"'
130 max%=(HIMEM-LOMEM-2048)DIV256:oldfs%=FNfs:IF max%<2:MODE &87:RUN
140 DIM ctrl% 31,data% 256*max%-1:X%=ctrl%:Y%=X%DIV256
150 PROCusb_Init:ON ERROR REPORT:PROCend:END
160 :
170 INPUTLINE"Source filing system: "type$
180 INPUTLINE"Source drive: "drv%
190 INPUTLINE"Dest. USB image file: "out$
200 OSCLI type$:thisfs%=FNfs
210 REPEAT:READ fs$,fn$,A$,retry%
220 UNTIL fs$="*" OR fs$=STR$thisfs%
230 IF fs$="*":PRINT "Unsupported filing system":PROColdfs:END
240 DATA 4,disk,7F,3, 8,adfs,72,1, 10,adfs,62,1, 16,hadfs,5A,1, 29,disk,77,1
250
260 DATA *,*,*,*
270 :
280
290 osw%=EVAL("&"+A$):dsize%=FNsize
300 PRINT"Total sectors to save (&";~dsize%;"): &";:INPUT""A$:IFA$<>"":dsize%=EVAL("&"+A$)
310 ON ERROR REPORT:IF INKEY-1:PROCend:END ELSE PROCabort:END
320 PROCusb_Sync:PROCusb_Flush
330 A%=FNusb_Cmd("IPA"):PROCusb_Flush:VDU13
340 IF FNusb_Cmd("IPA"):PROCabort:END
350 IF FNusb_Cmd("OPW "+out$):PROCabort:END
360 PROCusb_Sync
370 :
380 sect%=0:thisnum%=max%
390 REPEAT
400 num%=max%:IF sect%+num%>dsize%:num%=dsize%-sect%
410 IF thisnum%<num%:num%=thisnum%
420 thisnum%=FNread(sect%,num%)
430 VDU13:PRINT"Writing ";FNh0(sect%,6);"+";FNh0(thisnum%,2);
440 IF FNusb_Cmd("SEK "+STR$(sect%*256)):PROCabort:END
450 PROCusb_WrStr("WRF "+STR$(thisnum%*256)+CHR$13)
460 A%=thisnum%:CALL usb_WrData
470 sect%=sect%+thisnum%
480 IF num%=thisnum%:thisnum%=thisnum%*2:IF thisnum%>max%:thisnum%=max%
490 UNTILsect%>=dsize%
500 :
510 VDU13:PRINT"Closing";SPC14;
520 PROCusb_Sync:PROCusb_Flush
530 IF FNusb_Cmd("CLF "+out$):PROCabort
540 PROCusb_Cmd("SUD")
550 PROCusb_Sync
560 PROColdfs
570 VDU13:PRINT"Done";SPC17
580 END
590 :
600 DEFPROColdfs
610 IFoldfs%:OSCLI"FX143,18,"+STR$oldfs%:oldfs%=0
620 ENDPROC
630 :
640 DEFPROCabort
650 PROCusb_Flush:PROCusb_Cmd("CLF "+out$)
660 PROCusb_Cmd("SUD"):PROCusb_Flush
670 PROCend:ENDPROC
680 :
690 DEFPROCend
700 PROColdfs:PRINT
710 ENDPROC
720 :
730 DEFFNread(sect%,num%)
740 REPEAT
750 try%=retry%
760 REPEAT
770 VDU13:PRINT"Reading ";FNh0(drv%,1);":";FNh0(sect%,6);"+";FNh0(num%,2);
780 err%=FNattempt(num%):try%=try%-1
790 UNTIL try%<1 OR err%=0
800 IF err%:num%=(num%+2)DIV4
810 UNTIL err%=0 OR num%<1
820 =num%-(num%<1)
830 :
840 DEFFNattempt(num%)
850 IFfn$="disk" :err%=FNdisk( data%,&53,drv%,sect%DIV10,sect%MOD10,num%,osw%,1)
860 IFfn$="adfs" :err%=FNadfs( data%, 8,drv%,sect%,num%,osw%)
870 IFfn$="hadfs":err%=FNhadfs(data%,&80,drv%,sect%,num%,osw%)
880 VDU13:A%=FNdisk_err(err%,drv%,sect%,num%)
890 =err%
900 :
910 DEFFNsize
920 LOCAL size%
930 IFfn$="disk":sect%=1:err%=FNdisk(data%,&53,drv%,0,sect%,1,osw%,1):size%=data%?7+256*(data%?6 AND 3)
940 IFfn$="adfs":sect%=0:err%=FNadfs(data%,8,drv%,sect%,1,osw%):size%=data%!&FC AND &FFFFFF
950 IFfn$="hadfs":sect%=&46:err%=FNhadfs(data%,&80,drv%,sect%,1,osw%):size%=data%!28 AND &FFFFFF
960 VDU13:A%=FNdisk_err(err%,drv%,sect%,1)
970 =size%
980 :
990
1000
1010 DEFFNfs:LOCALA%,E%,Y%:=(USR&FFDA)AND&FF
1020 DEFFNdisk(addr%,cmd%,drv%,trk%,sec%,num%,osw%,den%):LOCALn%
1030 REPEAT:n%=num%:IFsec%+n%>10:n%=10-sec%
1040 REPEAT:X%?0=drv%+den%*24+8+2*(trk%DIV80):X%!1=addr%:X%?5=3-7*(cmd%>127)
1050 X%?6=cmd%:X%?7=trk%MOD80:X%?8=sec%:X%!9=n%OR&1E20:A%=osw%:CALL&FFF1
1060 A%=X%?(7+X%?5):UNTILA%<>&10:addr%=addr%+n%*256:num%=num%-n%:sec%=(sec%+n%)MOD10:trk%=trk%+1
1070 UNTILA%<>0ORnum%<1:=A%
1080 DEFFNadfs(addr%,cmd%,drv%,sect%,num%,osw%)
1090 X%?0=1:X%!1=addr%:X%?5=cmd%:X%?6=drv%*32+((sect%AND&1F0000)DIV65536)
1100 X%?7=((sect%AND&FF00)DIV256):X%?8=sect%:X%!9=num%:X%!11=0
1110 A%=osw%:CALL&FFF1:=?X%
1120 DEFFNhadfs(addr%,cmd%,drv%,sect%,num%,osw%)
1130 !X%=&600:X%!2=addr%:X%!6=sect%:X%?9=drv%:X%?10=num%:X%?11=cmd%
1140 A%=osw%:CALL&FFF1:=X%?12
1150 DEFFNdisk_err(A%,D%,S%,N%)
1160 IFA%:PRINT"Disk error ";FNh0(A%,2);" at ";FNh0(D%,1);":";FNh0(S%,6);"+";FNh0(N%,2)
1170 =A%
1180 :
1190
1200
1210 DEFFNh0(A%,N%):=RIGHT$("00000000"+STR$~A%,N%)
1220 DEFFNfx(A%,X%):LOCAL Y%:Y%=X%DIV256:=((USR&FFF4)AND&FFFF00)DIV256
1230 :
1240
1250
1260 DEFPROCusb_Sync:REPEATA%=?usb_D:UNTIL(?usb_S AND 128):ENDPROC
1270 DEFPROCusb_Flush:IF(?usb_S AND 128):ENDPROC
1280 PRINT'"Flushing USB";:REPEAT:REPEATA%=?usb_D:UNTIL(?usb_S AND 128)
1290 A%=TIME+20:REPEATUNTILTIME>A%:UNTIL(?usb_S AND 128):ENDPROC
1300 DEFFNusb_Err:IF?usb_result%=13 OR usb_result%?1=ASC":":=0 ELSE PRINT"USB Error: "$usb_result%:=TRUE
1310 DEFPROCusb_Cmd(A$):PROCusb_Sync:PROCusb_WrStr(A$+CHR$13):PROCusb_RdStr:ENDPROC
1320 DEFFNusb_Cmd(A$):PROCusb_Cmd(A$):=FNusb_Err
1330 DEFPROCusb_WrStr(A$):FOR A%=1 TO LEN A$:REPEATUNTIL(?usb_S AND 64)=0
1340 ?usb_D=ASCMID$(A$,A%,1):NEXT:ENDPROC
1350 DEFPROCusb_RdStr:A%=usb_result%-1:REPEATA%=A%+1:?A%=FNusb_Rd:UNTIL?A%=13:ENDPROC
1360 DEFPROCusb_Wr(A%):REPEATUNTIL(?usb_S AND 64)=0:?usb_D=A%:ENDPROC
1370 DEFFNusb_Rd:REPEATUNTIL(?usb_S AND 128)=0:=?usb_D
1380 DEFPROCusb_Init
1390 usb_D=&FCF8:usb_S=&FCF9
1400 usb_result%=usb_result%:IF usb_result%:ENDPROC
1410 DIM usb_result% 63,mc% 99
1420 FOR P=0 TO 1:P%=mc%:[OPT P*2
1430 .usb_RdData
1440 TAY:LDA #data% AND 255:STA usb_RdLp+4
1450 LDA #data% DIV 256:STA usb_RdLp+5:LDX #0
1460 .usb_RdLp:JSR usb_Rd:STA data%,X:INX:BNE usb_RdLp
1470 INC usb_RdLp+5:DEY:BNE usb_RdLp:RTS
1480 .usb_Rd:BIT usb_S:BPL usb_Rd2:BIT &FF:BPL usb_Rd
1490 .usb_Rd2:LDA usb_D:RTS
1500 .usb_WrData
1510 TAY:LDA #data% AND 255:STA usb_WrLp+1
1520 LDA #data% DIV 256:STA usb_WrLp+2:LDX #0
1530 .usb_WrLp:LDA data%,X:JSR usb_Wr
1540 .usb_WrLp2:LDA usb_D:BIT usb_S:BPL usb_WrLp2
1550 INX:BNE usb_WrLp
1560 INC usb_WrLp+2:DEY:BNE usb_WrLp:RTS
1570 .usb_Wr:BIT usb_S:BVC usb_Wr2:BIT &FF:BPL usb_Wr
1580 .usb_Wr2:STA usb_D:RTS
1590 ]NEXT:ENDPROC
1600 :