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