A MULTI-TASKING DISC FORMATTER

Glynn Clements presents a program which allows you to format floppies in the background.

While the Desktop does allow floppy discs to be formatted, it does so in a rather crude way. In particular, all other applications are suspended for the duration of the operation. The program here allows a disc to be formatted in the background, meaning that you can continue with other applications while the formatting takes place. In addition, discs can also be verified in a similar way.

ENTERING THE PROGRAM

Start by creating a new directory called !Format, and select this as the current directory. Enter the Desktop, and run the !Edit application. Use the 'Create new Obey file' option (from the iconbar menu) to enter listing 1, and save this as !Run. Next, go to Basic and enter listing 2. Save this with the name !Runimage. This should leave the directory !Format containing the two files !Run and !Runimage.

You might wish to design a sprite which will be used to represent the formatter. To do this, use Paint to create a mode 12 sprite which is 34 by 17 in size with no palette and no mask. Call this sprite !Format, and save it in a file called !Sprites within the !Format directory.

USING THE FORMATTER

The formatter is started by double clicking on the !Format directory. This pops up the window shown in figure 1. The four 'buttons' at the top right allow the drive to be selected. It is only possible to select drives which are actually fitted to the machine, the other buttons being greyed-out. The three buttons down the left hand side select the format to use - L, D or E. The two large buttons at the bottom right start the format, or verify, options. In the case of formatting, a disc name must be entered into the box titled Name before the operation can begin. You are also asked for confirmation before formatting.

While actually formatting or verifying, the bar at the bottom of the window shows the progress, with red indicating formatting, and green verifying. A disc is automatically verified after it has been formatted. The menu button pops up a menu which offers the option to abort the current operation, or to quit the formatter. Clicking on the close box of the window will also quit the formatter. Be warned, though, the operation of the entire system is very slugish while the formatting is in progress.

Listing 1

Set Format$Dir <Obey$Dir>
WimpSlot -min 32K -max 32K
Run <Format$Dir>.!RunImage

Listing 2

10 REM >!RunImage
20 REM Program Background Formatter
30 REM Version A 1.0
40 REM Author Glynn Clements
50 REM RISC User July/August 1989
60 REM Program Subject to Copyright
70 :
80 DIM bk% 100,buffer% 56,spArea% 700,data% 6500,rec% 64,dlist% 1024,icon_drive%(3)
90 SYS "Wimp_Initialise",200,&4B534154,"Formatter"
100 ON ERROR PROCerror(ERL,REPORT$)
110 spArea%!0=2000:spArea%!4=0
120 spArea%!8=16:spArea%!12=16
130 SYS"OS_SpriteOp",&10F,spArea%,"BarGraph",0,240,5,12
140 FOR i%=0 TO 239
150 FOR j%=0 TO 4
160 SYS"OS_SpriteOp",&12A,spArea%,"BarGraph",i%,j%,0
170 NEXT j%,i%
180 PROCwindow
190 SYS "Wimp_SetCaretPosition",handle%,icon_name%,,,-1,0
200 quit%=FALSE:quit_ok%=FALSE
210 mode%=-1
220 REPEAT
230 SYS "Wimp_Poll",FNmask,bk% TO reason%
240 CASE reason% OF
250 WHEN 0:IF mode%>-1 THEN PROCdo_track(drive%,format$,mode%)
260 WHEN 2:SYS "Wimp_OpenWindow",,bk%
270 WHEN 3:PROCclose_down(FNquit_ok)
280 WHEN 6:
290 change%=bk%!8 AND (NOT bk%!20)
300 IF(change% AND 5)ANDmode%=-1 THEN
310 CASE bk%!16 OF
320 WHEN icon_format%: PROCgo(0)
330 WHEN icon_verify%: PROCgo(1)
340 ENDCASE
350 ENDIF
360 IF (change% AND 2) THEN PROCmenu(bk%!0-64,bk%!4)
370 WHEN 8:
380 IF !bk%=handle% AND bk%!4=icon_name% AND mode%=-1 THEN
390 IF bk%!24=13 THEN PROCgo(0) ELSE SYS "Wimp_ProcessKey",bk%!24
400 ENDIF
410 WHEN 9:
420 IF bk%!0=0 THEN
430 PROCclose_down(FNquit_ok)
440 ELSE
450 mode%=-1:PROCupdate_bar(0,79,0)
460 ENDIF
470 WHEN 17,18:
480 CASE bk%!16 OF
490 WHEN 8:quit_ok%=FNquit_ok
500 WHEN 0:PROCclose_down(quit_ok%)
510 ENDCASE
520 ENDCASE
530 UNTIL quit%
540 SYS "Wimp_CloseDown"
550 END
560 :
570 DEF FNmask
580 IF mode%=-1 THEN =&33 ELSE =&32
590 :
600 DEF PROCmenu(x%,y%)
610 $bk%="Formatter":bk%!12=&70207
620 bk%!16=150:bk%!20=40:bk%!24=0
630 bk%!28=0:bk%!32=-1
640 bk%!36=&07090011:$(bk%+40)="Quit"
650 bk%!52=&80:bk%!56=-1
660 bk%!60=&07090011:IF mode%=-1 THEN bk%!60=(bk%!60 OR &400000)
670 $(bk%+64)="Abort"
680 SYS "Wimp_CreateMenu",,bk%,x%,y%
690 ENDPROC
700 :
710 DEF PROCgo(action%)
720 LOCAL answer%,sector%,ptr%,size%,i%
730 SYS"Wimp_WhichIcon",handle%,bk%,&3F0000,&220000
740 IF !bk%=-1 THEN ENDPROC
750 FOR i%=0 TO floppies%
760 IF icon_drive%(i%)=!bk% drive%=i%
770 NEXT i%
780 SYS"Wimp_WhichIcon",handle%,bk%,&3F0000,&210000
790 IF !bk%=-1 THEN ENDPROC
800 CASE !bk% OF
810 WHEN icon_l%:format$="L"
820 WHEN icon_d%:format$="D"
830 WHEN icon_e%:format$="E"
840 ENDCASE
850 rec%!12=&203:rec%!20=RND
860 $(rec%+22)=STRING$(42,CHR$(0))
870 $(rec%+22)=$title%
880 CASE format$ OF
890 WHEN "L":
900 rec%!0=&02011008:rec%!4=0
910 rec%!8=0:rec%!16=655360
920 WHEN "D":
930 rec%!0=&0202050A:rec%!4=0
940 rec%!8=0:rec%!16=819200
950 WHEN "E":
960 rec%!0=&0202050A:rec%!4=&1070F
970 rec%!8=&05200100:rec%!16=819200
980 ENDCASE
990 defects%=0
1000 IF action%=0 THEN
1010 IF $title%="" THEN ENDPROC
1020 !bk%=0
1030 $(bk%+4)="Format "+STR$(drive%)+" "+format$+" - Are you sure ?"
1040 SYS"Wimp_ReportError",bk%,&17 TO ,answer%
1050 IF answer%=1 THEN
1060 size%=rec%?0-7:ptr%=data%
1070 PROCbytes(60,&4E)
1080 FOR sector%=0 TO rec%?1-1
1090 PROCbytes(12,0):PROCbytes(3,&F5)
1100 PROCbytes(1,&FE):PROCbytes(1,0)
1110 PROCbytes(1,0)
1120 PROCbytes(1,sector%)
1130 PROCbytes(1,size%)
1140 PROCbytes(1,&F7):PROCbytes(22,&4E)
1150 PROCbytes(12,0):PROCbytes(3,&F5)
1160 PROCbytes(1,&FB)
1170 PROCbytes(128<<size%,&E5)
1180 PROCbytes(1,&F7):PROCbytes(24,&4E)
1190 NEXT sector%
1200 PROCbytes(1050-50*size%,&4E)
1210 mode%=0:verify%=FALSE
1220 ENDIF
1230 ELSE
1240 mode%=80:verify%=TRUE
1250 ENDIF:ENDPROC
1260 :
1270 DEF PROCbytes(n%,byte%)
1280 LOCAL i%
1290 FOR i%=0 TO n%-1
1300 ptr%?i%=byte%
1310 NEXT i%:ptr%+=n%:ENDPROC
1320 :
1330 DEF PROCdo_track(drive%,format$,RETURN mode%)
1340 LOCAL track%,action%,sector%,ptr%,size%,fsize%,a1%,a2%,f%,errorp%
1350 track%=mode% MOD 80
1360 action%=mode% DIV 80
1370 IF action%=2 THEN
1380 PROCcreate_struc(drive%,format$)
1390 mode%=-1:PROCupdate_bar(0,79,0)
1400 SYS"XOS_CLI","ADFS:Dismount :"+STR$~drive%
1410 ELSE
1420 CASE format$ OF
1430 WHEN "L":
1440 a1%=track%*4096
1450 a2%=track%*4096+327680
1460 WHEN "D","E":
1470 a1%=track%*10240
1480 a2%=track%*10240+5120
1490 ENDCASE
1500 a1%=a1% OR (drive%<<29)
1510 a2%=a2% OR (drive%<<29)
1520 CASE action% OF
1530 WHEN 0:
1540 size%=84+(1<<(rec%?0))
1550 FOR sector%=0 TO rec%?1-1
1560 ptr%=data%+sector%*size%
1570 ptr%?76=track%:ptr%?77=0
1580 NEXT sector%
1590 SYS"ADFS_DiscOp",,4 OR (rec%<<6),a1%,data%
1600 FOR sector%=0 TO rec%?1-1
1610 ptr%=data%+sector%*size%:ptr%?77=1
1620 NEXT sector%
1630 SYS"ADFS_DiscOp",,4 OR (rec%<<6),a2%,data%
1640 WHEN 1:
1650 size%=rec%?1<<rec%?0
1660 SYS"XADFS_DiscOp",,1 OR (rec%<<6),a1%,data%,size% TO errorp%;f%
1670 IF (f% AND 1) THEN PROCbad(a1%,format$,errorp%)
1680 SYS"XADFS_DiscOp",,1 OR (rec%<<6),a2%,data%,size% TO errorp%;f%
1690 IF (f% AND 1) THEN PROCbad(a2%,format$,errorp%)
1700 ENDCASE
1710 PROCupdate_bar(track%,track%,11-action%):mode%+=1
1720 ENDIF:ENDPROC
1730 :
1740 DEF PROCbad(addr%,format$,errorp%)
1750 LOCAL i%,f%,size%
1760 IF (!errorp% AND &FFFFFF) <> &108C7 THEN ENDPROC
1770 IF format$="E" AND NOT verify% THEN
1780 FOR i%=0 TO 4
1790 SYS"XADFS_DiscOp",,1 OR (rec%<<6),addr%+i%*1024,data%,1024 TO ;f%
1800 IF (f% AND 1) THEN PROCmark(addr%+i%*1024)
1810 NEXT i%
1820 ELSE
1830 OSCLI"Error 0 Bad Sector at &"+STR$~(addr%)
1840 ENDIF:ENDPROC
1850 :
1860 DEF PROCmark(addr%)
1870 IF defects%>254 THEN
1880 *Error 0 Too many bad sectors
1890 ELSE
1900 dlist%!(defects%*4)=addr%
1910 defects%+=1:ENDPROC
1920 :
1930 DEF PROCerror(err%,err$)
1940 bk%!0=err%:$(bk%+4)=err$+" (Error Code "+STR$err%+")"
1950 SYS"Wimp_ReportError",bk%,&11
1960 mode%=160:ENDPROC
1970 :
1980 DEF PROCcreate_struc(drive%,format$)
1990 LOCAL flags%,size%,ssize%
2000 IF verify% THEN ENDPROC
2010 CASE format$ OF
2020 WHEN "L":flags%=&C0
2030 WHEN "D":flags%=&40
2040 WHEN "E":flags%=0
2050 ENDCASE
2060 dlist%!(defects%*4)=&20000000
2070 SYS"FileCore_FloppyStructure",data%,rec%,flags%,dlist% TO ,,,size%
2080 ssize%=1<<rec%?0
2090 size%=(size%+ssize%-1)DIVssize%*ssize%
2100 SYS"ADFS_DiscOp",,2 OR rec%<<6,drive%<<29,data%,size%:ENDPROC
2110 :
2120 DEF PROCupdate_bar(start%,end%,colour%)
2130 LOCAL i%,j%
2140 FOR i%=start%*3 TO end%*3+2
2150 FOR j%=0 TO 4
2160 SYS"OS_SpriteOp",&12A,spArea%,"BarGraph",i%,j%,colour%
2170 NEXT j%,i%
2180 SYS"Wimp_ForceRedraw",handle%,8+start%*6,-324,14+end%*6,-308:ENDPROC
2190 :
2200 DEF FNquit_ok
2210 LOCAL answer%,quit_ok%,action$
2220 IF mode%<80 THEN action$="Format" ELSE action$="Verify"
2230 IF mode%>-1 THEN
2240 !bk%=0:$(bk%+4)="Abort "+action$+"
- Are you sure ?"
2250 SYS"Wimp_ReportError",bk%,&17 TO ,answer%:quit_ok%=(answer%=1)
2260 ELSE
2270 quit_ok%=TRUE
2280 ENDIF
2290 =quit_ok%
2300 :
2310 DEF PROCclose_down(quit_ok%)
2320 IF quit_ok% THEN
2330 !bk%=handle%
2340 SYS "Wimp_CloseWindow",,bk%
2350 mode%=-1:quit%=TRUE
2360 ENDIF:ENDPROC
2370 :
2380 DEF PROCwindow
2390 LOCAL temp%,flags%
2400 bk%!0=400:bk%!4=400:bk%!8=900
2410 bk%!12=736:bk%!16=0:bk%!20=0
2420 bk%!24=-1:bk%!28=&87030012
2430 bk%!32=&01070207:bk%!36=&000C0103
2440 bk%!40=0:bk%!44=-336:bk%!48=500
2450 bk%!52=0:bk%!56=&3D:bk%!60=&3000
2460 bk%!64=spArea%:bk%!68=0
2470 $(bk%+72)="Formatter":bk%!84=0
2480 SYS"Wimp_CreateWindow",,bk% TO handle%
2490 temp%=FNicon(8,-288,102,-240,&C7000011,0,0,0,"Name:")
2500 temp%=FNicon(354,-56,462,-8,&C7000011,0,0,0,"Drive:")
2510 temp%=FNicon(8,-56,140,-8,&C7000011,0,0,0,"Format:")
2520 $(buffer%)="640k, Old Map"
2530 temp%=FNicon(76,-112,296,-64,&C7000119,buffer%,-1,14,"")
2540 $(buffer%+14)="800k, Old Map"
2550 temp%=FNicon(76,-168,296,-120,&C7000119,buffer%+14,-1,14,"")
2560 $(buffer%+28)="800k, New Map"
2570 temp%=FNicon(76,-224,296,-176,&C7000119,buffer%+28,-1,14,"")
2580 icon_l%=FNicon(8,-112,66,-64,&C701503D,0,0,0,"L")
2590 icon_d%=FNicon(8,-168,66,-120,&C701503D,0,0,0,"D")
2600 icon_e%=FNicon(8,-224,66,-176,&C721503D,0,0,0,"E")
2610 SYS"ADFS_Drives" TO ,floppies%
2620 icon_drive%(0)=FNicon(354,-112,408,-64,&C722503D,0,0,0,"0")
2630 icon_drive%(1)=FNicon(432,-112,486,-64,FNff(1),0,0,0,"1")
2640 icon_drive%(2)=FNicon(354,-168,408,-120,FNff(2),0,0,0,"2")
2650 icon_drive%(3)=FNicon(432,-168,486,-120,FNff(3),0,0,0,"3")
2660 title%=buffer%+42
2670 $(title%)=""
2680 $(buffer%+53)="a~ "
2690 icon_name%=FNicon(110,-288,296,-240,&0700F13D,title%,buffer%+53,11,"")
2700 icon_format%=FNicon(354,-228,488,-176,&0B03903D,0,0,0,"Format")
2710 icon_verify%=FNicon(354,-288,488,-236,&0D03903D,0,0,0,"Verify")
2720 icon_bargraph%=FNicon(8,-328,488,-304,&07000006,0,0,0,"BarGraph")
2730 !bk%=handle%
2740 SYS"Wimp_GetWindowState",,bk%
2750 SYS"Wimp_OpenWindow",,bk%
2760 ENDPROC
2770 :
2780 DEF FNff(drive%)
2790 IF drive%>=floppies% THEN = &C742503D ELSE =&C702503D
2800 :
2810 DEF FNicon(x0%,y0%,x1%,y1%,flags%,data1%,data2%,data3%,text$)
2820 LOCAL han%
2830 bk%!0=handle%:bk%!4=x0%:bk%!8=y0%
2840 bk%!12=x1%:bk%!16=y1%
2850 bk%!20=flags%
2860 IF text$="" THEN
2870 bk%!24=data1%:bk%!28=data2%
2880 bk%!32=data3%
2890 ELSE
2900 $(bk%+24)=LEFT$(text$,11)
2910 ENDIF
2920 SYS"Wimp_CreateIcon",,bk% TO han%
2930 =han%