home *** CD-ROM | disk | FTP | other *** search
- {
- To: INFO-IBMPC-REQUEST@USC-ISIB.ARPA
- From: U001222%HNYKUN11.BITNET@WISCVM.WISC.EDU
- Subject: reformat.pas
- }
- PROGRAM reformat;
- {
- Program to reformat any disk attached to an Olivetti PC or compatible.
- The progam will work well on any MS/PC-DOS machine running under DOS
- versions 2.00 up to and including 3.10. Fixed disks up to 32 Meg.
-
- V1.50 Extensions made for big FATs. WORD.INC included for handling of
- word integers. MS-DOS function INT21 / 32H used for drive information.
- Corrected the problem of DOS losing track of the current directory.
-
- The program has been tested under DOS 2.00 thru 3.10
- It will probably work under DOS 3.20 too, but this version will not
- run when you try to do so. If you want to test it with DOS 3.20, look
- for the string DOS_Versions (it's somewhere near the end of the program)
- in this program, and include that version number into the test.
- Please let the author know whether you had success or not.
-
- Jos Wennmacker July 86.
- Universitair Rekencentrum
- Geert Grooteplein Zuid 41
- 6525 GA Nijmegen
- The Netherlands
-
- BITNET address: U015415 at HNYKUN22
-
- v1.6, 23 Nov 89 David Kirschbaum, Toad Hall
- - Recoded for TP v5.0
-
-
- V1.5 Jos added new 16-bit and word code, handling up to 30Meg
- hard disks, etc. I cleaned up the integer math inline procedures
- a little.
- David Kirschbaum, Toad Hall
-
- V1.23 Added FRAMER.INC, WRITEF.INC for framing, fast screen write,
- fast screen line clear. Tightened up displays a little.
- This version is now VERY PC-specific. Generic MS-DOS functions
- for screen stuff to follow.
- David Kirschbaum, Toad Hall.
-
- V1.22 Added inline code to replace the INT25.ASM and INT26.ASM
- files.
- David Kirschbaum, Toad Hall, 3 May 86
-
- V1.21(mod) not publicly released. Changes made by Rick Watson to let
- the program recognize the big (16 bit) FATs. He made it run on 20 Meggers
- under DOS 3.x. Martin Hobson made it run on 30 Meggers under DOS 3.x.
- May 86.
-
- V1.21 Small corrections made to avoid Turbo integer overflow. (Hey,
- Borland, what about a WORD type in Turbo, would be very usefull using
- the MSDOS features!).
-
- V1.20 First release to the public domain.
- What started as a favour to a friend grew into a nice program.
- Do you like it? Let me know about it! If I know many people to use it,
- I'll keep it up to date, and send you new releases.
- Jos Wennmacker
-
- }
- {$A+} {word alignment to be nice}
- {$B-} {short-circuit Boolean Eval}
- {$D-} {no debug}
- {$F-} {no far calls}
- {$L-} {no local information}
- {$R-} {no range checking}
- {$S-} {no stack checking}
- {$V-} {no string checking}
-
- Uses Dos,Crt; {v1.6}
-
- {-------------------------------- Global types -------------------------------}
-
- TYPE
-
- {------------------- types for word arithmetic see REFORMAT.IN1 -------------}
-
- Relational_Operator = (Eq, Gt, Lt, Ne, Ge, Le);
-
-
- {----------------------------- Bootrecord layout -----------------------------}
-
- Boot = { the layout of the DOS boot record}
- RECORD
- Jump: ARRAY[0..2] OF Byte; { Near jump to boot code}
- OEM : ARRAY[0..7] OF CHAR; { eight character OEM name}
- sectorSize: word; { number of bytes in one sector}
- clusterSize: Byte; { sectors per cluster}
- reservedSectors: word; { DOS boot code sector(s) typically 1}
- numberOfFATs: Byte; { usually 2, but often 1 for RAM disks}
- rootDirSize, { maximum entries in root directory}
- totalSectors: word; { total sectors in the logical image}
- { A limited description of the drive
- bit 0 = 1: twosided, 0: not two-sided
- bit 1 = 1: 8-sector, 0: not 8-sector
- bit 2 = 1: removable 0: not removable
- bits 3-7 must be set to 1
- }
- mediaDescriptor: Byte;
- fatSize, { number of sectors in each FAT copy}
- trackSize, { number of sectors per track}
- numberOfHeads, { number of heads}
- { sectors hidden from DOS, preceding the DOS partition: including the
- master boot record and any non-DOS partitions
- }
- hiddenSectors: word;
- END;
-
- {---------------- Layout of DOS function 32h disk parameter block ------------}
-
- Parms_32 = ^Parameter_table;
-
- Parameter_Table = { layout of the DOS function 32 table}
- RECORD
- assignedDisk, { 0 = A, 1 = B, ...}
- altAD: Byte; { same as above, but 0 for RAM disk}
- sectorSize: word; { number of bytes in one sector}
- clusterSize_1, { sectors per cluster minus 1}
- numberOfHeads_1: Byte; { number of heads minus 1}
- reservedSectors: word; { DOS boot code sector(s) typically 1}
- numberOfFATs: Byte; { usually 2, but often 1 for RAM disks}
- rootDirSize, { maximum entries in root directory}
- firstDataSector, { first sector for data storage}
- totalDataClusters_1: word; { total data clusters plus 1}
- fatSize: Byte; { number of sectors in each FAT copy}
- firstDirectorySector: word; { first sector of the root directory}
- (* v1.6
- DeviceDriverAddress: ^byte; { Far (offset, segment) address of the
- DOS device driver for the drive}
- *)
- DeviceDriverAddress: Pointer; {v1.6}
- { A limited description of the drive
- only the low order byte is used:
- bit 0 = 1: twosided, 0: not two-sided
- bit 1 = 1: 8-sector, 0: not 8-sector
- bit 2 = 1: removable 0: not removable
- bits 3-7 must be set to 1
- }
- mediaDescriptor: word;
- NextParameterTable: Parms_32; { far pointer to next disk table}
- { Starting cluster of current working directory.
- According to Glenn Roberts in his May 86 PC Tech Journal article
- "Finding Disk Parameters" this would only hold for PC DOS 2.00
- }
- currentDirCluster: word;
- CurrentDirName: ARRAY [0..63] OF CHAR
- { The name of the current working directory. This does not hold for
- DOS 3.x versions. Only for 2.00
- }
- END;
-
- {-------- Long byte and integerarays for Disk Transfer Area, Fats etc. -------}
-
- intArray = ARRAY[0..32766] OF Word; {v1.6 INTEGER;}
-
- buffer = ARRAY[0..32766] OF Byte;
-
- {--------------------- Element of tree of directory entries ------------------}
-
- DirectoryPointer = ^DirectoryEntry;
-
- (*v1.6 longInteger = ARRAY[0..1] OF INTEGER; *)
-
- DirectoryEntry =
- RECORD
- { name + extension w/o period
- If the first char is $00, then this entry was never used.
- Also the next entries in this directory have never been used.
- If the first char is $E5, then this entry was erased.
- }
- EntryName: ARRAY[0..10] OF CHAR;
- { attribute of entry:
- bit if set means
- 0 read only file
- 1 hidden file
- 2 system file
- 3 volume label
- 4 subdirectory
- 5 archive bit
- }
- attribute: Byte;
- reserved: ARRAY[1..10] OF Byte; { for future use}
- { mapped in the bits:
- < hh > < mm > < xx >
- 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- where:
- hh binary number of hours [0..23]
- mm binary number of minutes [0..59]
- xx binary number of two-second
- increments [0..28]
- }
- timeLastUpdated: word;
- { mapped in the bits
- < yy > < mm > < dd >
- 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- where:
- yy binary number of years [0..119]
- (1980-2099)
- mm binary number of month [1..129]
- dd binary number of day [1..31]
- }
- dateLastUpdated: word;
- startingCluster: word; { index of the file's first cluster}
- fileSize: longint; { filesize in bytes v1.6}
- newStartingCluster: word;
- Next,
- SubDirectory: DirectoryPointer;
- END;
-
- {------------------------------- Helps for I/O -------------------------------}
-
- WorkString = STRING[255];
- Line = STRING[78];
- Str40 = STRING[40];
-
- Disk_Activity = (reading,writing);
-
- {-------------------------------- constants ----------------------------------}
-
- CONST
-
- Header: STRING[37] = ' REFORMAT: an original JOS disk tool ';
- Version: STRING[10] = 'Ver: 1.60 ';
- PDS: STRING[24] = ' Public Domain Software ';
- EnterStr: STRING[28] = 'Press Enter to return to DOS';
- HiSpace: STRING[01] = #160; {WriteF blank line flag}
-
- {--------------------------- FAT special values ------------------------------}
-
- unused: word = $0000; { we use typed constants, because}
- reservedMinimum: word = $0FF0; { we might have to change these values}
- reservedMaximum: word = $0FF6; { the values entered here are for}
- badCluster: word = $0FF7; { the old, small FAT format of 12 bits}
- lastMinimum: word = $0FF8; { per entry. The new FAT format uses}
- lastMaximum: word = $0FFF; { 16 bit-entries. See the procedure}
- lastNormal: word = $0FFF; { Getinformation.}
-
- {---------------------- file attribute byte values----------------------------}
-
- READONLY = $01; { file attribute byte}
- HIDDENFILE = $02;
- SYSTEMFILE = $04;
- VOLUMELABEL = $08;
- SUBDIRECTORY = $10;
- ARCHIVE = $20;
-
- NEVERUSED = $00; { first byte of file's name}
- ERASED = $E5;
-
- FIXEDDISK = $F8; { some values of mediaDescriptor}
- DUAL8SECTOR = $FF;
- SINGLE8SECTOR = $FE;
- DUAL9SECTOR = $FD;
- SINGLE9SECTOR = $FC;
-
- {---------- constants for the screen layout, for FRAMER and WRITEF procedures}
-
- MIDDLEFIELDY = 18; { little window in the middle}
- INPUTFIELDX = 22; { User Input Field}
- INPUTFIELDY = 20;
- LOGFIELDX = 22; { Activity Logging}
- LOGFIELDY = 21;
- WARNINGFIELDX = 22; { Warning Message Field}
- WARNINGFIELDY = 22;
- ERRORFIELDX = 22; { Error Message Field}
- ERRORFIELDY = 23;
- DISASTERFIELDX = 22; { Disaster Message Field}
- DISASTERFIELDY = 24;
-
- {-------- Drive characteristics and constants communications block -----------}
-
- VAR
-
- DriveLetter: CHAR;
- driveNumber: Byte;
- defaultDrive: Byte;
-
- totalSectors,
- sectorSize: word;
- media: Byte;
- trackSize,
- numberOfHeads,
- hiddenSectors,
- reservedSectors,
- rootDirSize: word;
- numberOfFATs: Byte;
- fatSize: word;
- clusterSize: Byte;
- firstDataSector,
- firstDirectorySector,
- totalDataClusters,
- freeClusters,
- badClusters,
- usedClusters: word;
- DeviceDriverAddress: Pointer; {v1.6 ^byte;}
- CurrentDirectory: ARRAY[0..63] OF CHAR;
- DiskLabel: STRING[11];
- diskCreationDate,
- diskCreationTime: word;
- OEM: ARRAY[0..7] OF CHAR;
- assignedDisk,
- altAD: Byte;
-
- BigFAT: BOOLEAN;
-
- firstFATsector,
- directorySectors: word;
-
- {----------------------------- Global variables ------------------------------}
-
- Register: Registers; {v1.6 Regpack;}
-
- oldFATindex,
- newFATindex: word;
- totalFiles,
- hiddenFiles,
- hiddenDirectories,
- inRootDirectory,
- inSubdirectories,
- nonContiguousFiles,
- subdirectories,
- movedClusters,
- clustersToMove,
- lostClusters,
- errors,
- count: Word; {v1.6 INTEGER;}
-
- SAVEaddress,
- DTAddress: ^buffer;
-
- PermutationAddress,
- NewFATAddress,
- OldFATAddress: ^intArray;
-
- RootDir: DirectoryPointer;
-
- {---------------------------------- miscellaneous vars -----------------------}
-
- hour,
- min,
- sec,
- frac: Word; {v1.6 INTEGER;}
- time: REAL;
-
- movedFieldX,
- movedFieldY: Word; {v1.6 INTEGER;}
-
- Instr: CHAR;
- AlreadyWritten: BOOLEAN;
- TmpStr: STRING[2];
- NrStr,
- S40: Str40;
- Legals: STRING[3];
- Parms: Line;
-
- {-----------------------------------------------------------------------------}
- { I REFORMAT.IN1} {Nijmegen .. word arithmetic v1.6 no longer needed}
- {$I REFORMAT.IN2} {Toad Hall.. InLine code FOR Int25 AND Int26}
- {$I REFORMAT.IN3} {Toad Hall.. fast screen framer, FRAMER.INC}
- {$I REFORMAT.IN4} {Toad Hall.. better screen writing AND clearing, WRITEF.INC}
- {-----------------------------------------------------------------------------}
-
- {----------------------- general screen I/O routines -------------------------}
-
- PROCEDURE Beep;
- BEGIN
- WRITE(CHR(7));
- END; { of Beep}
-
- PROCEDURE WriteLog(Text: Line);
- BEGIN
- WriteF(LOGFIELDX, LOGFIELDY, HiSpace);
- WriteF(LOGFIELDX, LOGFIELDY, Text);
- END; { of WriteLog}
-
- PROCEDURE WriteWarning(Text: Line);
- BEGIN
- WriteF(WARNINGFIELDX, WARNINGFIELDY, HiSpace);
- WriteF(WARNINGFIELDX, WARNINGFIELDY, Text);
- END; { of WriteWarning}
-
- PROCEDURE WriteError(Text: Line);
- BEGIN
- WriteF(ERRORFIELDX, ERRORFIELDY, HiSpace);
- WriteF(ERRORFIELDX, ERRORFIELDY, Text);
- END; { of WriteError}
-
- PROCEDURE WriteDisaster(Text: Line);
- BEGIN
- WriteF(DISASTERFIELDX, DISASTERFIELDY, HiSpace);
- WriteF(DISASTERFIELDX, DISASTERFIELDY, Text);
- END; { of WriteDisaster}
-
- PROCEDURE BlankFields;
- BEGIN
- WriteError(' ');
- WriteWarning(' ');
- WriteDisaster(' ');
- IF Instr = 'I' THEN Register.flags := 0;
- END; { of BlankFields}
-
- PROCEDURE GetInput(Prompt: Str40; VAR Instr: CHAR);
- BEGIN
- WriteF(INPUTFIELDX, INPUTFIELDY, HiSpace); { really only needs 1}
- WriteF(INPUTFIELDX, INPUTFIELDY, Prompt + ': ');
- Beep;
- (* v1.6
- REPEAT UNTIL KeyPressed;
- READ(Kbd, Instr);
- Instr := UpCase(Instr);
- *)
- Instr := UpCase(ReadKey); {v1.6}
- WRITE(Instr);
- END; { of GetInput}
-
- PROCEDURE Exeunt(Prompt: Str40); { we do this a lot}
- BEGIN
- GetInput(Prompt, Instr);
- Height := 25;
- WriteF(1, 24, HiSpace); { clear bottom line and leave screen
- for user to contemplate}
- HALT;
- END; { of Exeunt}
-
- {---------------------------- timer control routines -------------------------}
-
- PROCEDURE StartTimer;
- {
- We want to let the user know how long REFORMAT took to do the job.
- }
- BEGIN
- (* In Turbo:
- with Register do begin
- ah := $2C;
- msdos(Register);
- hour := hi(cx);
- min := lo(cx);
- sec := hi(dx);
- frac := lo(dx);
- end;
- *)
- {Toad Hall note: tighter, quicker inline}
- InLine(
- $B4/$2C { mov ah,$2C}
- /$CD/$21 { int $21}
- /$31/$C0 { xor ax,ax ;clear msb}
- /$86/$E8 { xchg al,ch ;the hour}
- /$A3/>HOUR { mov [>hour],ax}
- /$86/$C8 { xchg al,cl ;the minute}
- /$A3/>MIN { mov [>min],ax}
- /$86/$F0 { xchg al,dh ;the second}
- /$A3/>SEC { mov [>sec],ax}
- /$86/$D0 { xchg al,dl ;the fraction}
- /$A3/>FRAC { mov [>frac],ax}
- );
- END; { of StartTimer}
-
- PROCEDURE StopTimer;
- {
- We want to let the user know how long REFORMAT took to do the job.
- }
- BEGIN
- (* In Turbo:
- with Register do begin
- ah := $2C;
- msdos(Register);
- frac := lo(dx) - frac;
- if frac < 0 then begin
- frac := frac + 100;
- sec := succ(sec);
- end;
-
- sec := hi(dx) - sec;
- if sec < 0 then begin
- sec := sec + 60;
- min := succ(min);
- end
- else if sec >= 60 then begin
- sec := sec - 60;
- min := pred(min);
- end;
-
- min := lo(cx) - min;
- if min < 0 then begin
- min := min + 60;
- hour := succ(hour);
- end
- else if min >= 60 then begin
- min := min - 60;
- hour := pred(hour);
- end;
- hour := hi(cx) - hour;
- end;
- *)
- {Toad Hall Note: Tighter, faster inline. You won't BELIEVE
- what a kludge Turbo makes of the above routine.
- }
- InLine(
- $B4/$2C { mov ah,$2C}
- /$CD/$21 { int $21}
- /$BB/>FRAC { mov bx,>frac ;fraction offset}
- /$BE/>SEC { mov si,>sec ;seconds offset}
- /$31/$C0 { xor ax,ax ;clear msb}
- /$86/$D0 { xchg al,dl ;get fraction}
- /$2B/$07 { sub ax,[bx] ;frac = lo(dx)-frac}
- /$73/$05 { jnc S1 ;no carry, so not <0}
- /$05/$64/$00 { add ax,100 ;<0, adjust}
- /$FF/$04 { inc word [si] ;bump seconds}
- {S1:}
- /$89/$07 { mov [bx],ax ;save fraction}
- /$BB/>MIN { mov bx,>min ;get Minute offset}
- /$31/$C0 { xor ax,ax ;clear msb}
- /$BF/$3C/$00 { mov di,60 ;constant}
- /$86/$F0 { xchg al,dh ;get seconds}
- /$2B/$04 { sub ax,[si] ;sec = hi(dx)-sec}
- /$73/$06 { jnc S2 ;not <0}
- /$01/$F8 { add ax,di ;<0, adjust}
- /$FF/$07 { inc word [bx] ;min=min+1}
- /$EB/$08 { jmp short S3}
- {S2:}
- /$39/$F8 { cmp ax,di ;>=60?}
- /$72/$04 { jb S3 ; nope}
- /$29/$F8 { sub ax,di ; sec=sec-60}
- /$FF/$0F { dec word [bx] ;min=min-1}
- {S3:}
- /$89/$04 { mov [si],ax ;save seconds}
- /$BE/>HOUR { mov si,>hour ;hour offset}
- /$31/$C0 { xor ax,ax ;clear msb}
- /$86/$C8 { xchg al,cl ;get minutes}
- /$2B/$07 { sub ax,[bx] ;min=lo(cx)-min}
- /$73/$06 { jnc S4 ; not below 0}
- /$01/$F8 { add ax,di ;min=min+60}
- /$FF/$04 { inc word [si] ;hour=hour+1}
- /$EB/$08 { jmp short S5}
- {S4:}
- /$39/$F8 { cmp ax,di ;>=60?}
- /$72/$04 { jb S5 ; nope}
- /$29/$F8 { sub ax,di ;min=min-60}
- /$FF/$0C { dec word [si] ;hour=hour-1}
- {S5:}
- /$89/$07 { mov [bx],ax ;save minutes}
- /$31/$C0 { xor ax,ax ;clear msb}
- /$86/$E8 { xchg al,ch ;get hour}
- /$2B/$04 { sub ax,[si] ;hour=hi(cx)-hour}
- /$89/$04 { mov [si],ax}
- );
- END; { of StopTimer}
-
- {$I REFORMAT.IN5} {Nijmegen .. disk, FAT, directory, misc. routines}
-
-
- {------------------------------ MAIN PROGRAM ---------------------------------}
-
- BEGIN
- { v1.6 Permitting user override of precautionary abort
- for DOS versions above 3.10
-
- Check_DOS_Version;
- }
- color := LIGHTGRAY; { initialize global screen attribute }
-
- IF paramcount = 0 { exactly one parameter allowed }
- THEN Parms := ''
- ELSE IF paramcount = 1
- THEN Parms := ParamStr(1)
- ELSE Parms := 'in error'; { force error message }
-
- IF LENGTH(Parms) <> 0
- THEN IF Parms[1] = '?' { display explanation screens }
- THEN BEGIN
- WriteDoc;
- HALT;
- END
- ELSE IF ( LENGTH(Parms) > 2 ) { we accept only d or d: }
- OR ( (LENGTH(Parms) = 2) AND (Parms[2] <> ':') )
- THEN BEGIN
- WRITELN;
- WRITELN('Invalid parameter: REFORMAT d: or ?');
- HALT;
- END
- ELSE Instr := Parms[1]
- ELSE Instr := ' ';
-
- InitCounters;
- InitScreen;
-
- GetInformation;
- {
- The TURBO procedures getmem, move and fillchar will behave the way we want
- in case the integer parameters are greater than 32767. (i.e. negative
- when interpreted as integers). Block allocation, block move and block
- filling can handle as many as 65535 bytes. Allocation however should
- never be done in quantities of more than 65521 bytes, because the
- pointer values are normalized, which means that the offset will be
- in the range 0 through 15. Segments must begin on a paragraph boundary.
- }
- (* v1.6
- GetMem( OldFATaddress, W_mul(totalDataClusters + 2, 2));
- GetMem( DTAddress, W_mul(sectorSize, fatSize));
- *)
- GetMem( OldFATaddress, (totalDataClusters + 2) ShL 1); {v1.6}
- GetMem( DTAddress, (sectorSize * fatSize) ); {v1.6}
- ReadFat( OldFATaddress^, DTAddress^);
-
- (* v1.6
- GetMem( NewFATaddress, W_mul(totalDataClusters + 2, 2));
- GetMem( PermutationAddress, W_mul(totalDataClusters + 2, 2));
- GetMem( SAVEaddress, W_mul(sectorSize, clusterSize));
- *)
- GetMem( NewFATaddress, (totalDataClusters + 2) ShL 1); {v1.6}
- GetMem( PermutationAddress, (totalDataClusters + 2) ShL 1); {v1.6}
- GetMem( SAVEaddress, sectorSize * clusterSize); {v1.6}
-
- ReadDirectories( DTAddress^ );
-
- Move( OldFATaddress^,
- (* v1.6
- NewFATaddress^, W_mul(totalDataClusters + 2, 2));
- *)
- NewFATaddress^, (totalDataClusters + 2) ShL 1); {v1.6}
-
- CheckDisk( NewFATaddress^, RootDir);
- (* v1.6
- FillChar( NewFATaddress^, W_mul(totalDataClusters + 2, 2), 0);
- *)
- FillChar( NewFATaddress^, (totalDataClusters + 2) ShL 1, 0); {v1.6}
- FOR count := 0 TO SUCC(totalDataClusters) DO
- PermutationAddress^[count] := count;
- Move(OldFATaddress^, NewFATaddress^, 4);
- RemakeFAT(OldFATaddress^, NewFATaddress^,
- PermutationAddress^, RootDir, 0, 0);
-
- LinkFreeClusters(OldFATaddress^, NewFATaddress^);
- CountClustersToMove(PermutationAddress^);
-
- WriteStatistics;
-
- {v1.6 Up to now, we've done nothing destructive and maybe have shown
- the user something informative (like will this sucker work with his
- DOS 4.01?) or whatever.
- NOW we ask him to take his life in his own hands...
- }
-
- Check_DOS_Version; {v1.6 moved down here.
- may abort and die.}
-
- IF nonContiguousFiles = 0
- THEN IF clustersToMove <> 0
- THEN BEGIN
- color := $70; { inverse }
- WriteF(0, middleFieldY,
- 'All files are contiguous, continue anyway?');
- color := LIGHTGRAY;
- REPEAT
- GetInput('Continue? (Y/N)',Instr);
- UNTIL Instr IN ['Y','N'];
- IF Instr = 'N'
- THEN Exeunt(EnterStr);
- END
- ELSE BEGIN
- WriteLog('Cannot make your disk more optimized!');
- Exeunt(EnterStr);
- END
- ELSE IF clustersToMove = 0
- THEN BEGIN
- WriteLog('Bad space makes file(s) noncontiguous.');
- Exeunt(EnterStr);
- END;
-
- IF media = FIXEDDISK
- THEN BEGIN
- color := $70; { inverse }
- WriteF(0, middleFieldY,
- 'Fixed disk: did you uninstall all protected software?');
- color := LIGHTGRAY;
- REPEAT
- GetInput('Continue? (Y/N)',Instr);
- UNTIL Instr IN ['Y','N'];
- IF Instr = 'N'
- THEN Exeunt(EnterStr);
- END;
-
- ResetDisk;
- StartTimer;
- WriteFAT(NewFATaddress^, DTAddress^);
- WriteDirectories(DTAddress^);
- DoIt(PermutationAddress^, DTAddress^, SAVEaddress^);
- ResetDisk;
- ResetSubdirectory;
- StopTimer;
- STR(hour:2, TmpStr);
- Nrstr := TmpStr + ' h ';
- STR(min:2, TmpStr);
- NrStr := NrStr + TmpStr + ' m ';
- STR(sec:2, TmpStr);
- NrStr := NrStr + TmpStr + '.';
- STR(frac:2, TmpStr);
- NrStr := NrStr + TmpStr + ' s';
- WriteLog('Done in: '+ NrStr + ' !');
-
- Exeunt(EnterStr);
- END.