Category : Files from Magazines
Archive   : PJ72.ZIP
Filename : FORMAT.PAS

 
Output of file : FORMAT.PAS contained in archive : PJ72.ZIP

{ sample code fragments from John Newlin's "Disk Formatting" }

AddressFieldType = record
TrackNum,HeadNum,SectNum,SizeCode : byte;
End;
Const
MaxSectors = 18;
Disk360Params : array[0..10] of byte =
($DF,$02,$25,$02,$09,$2A,$FF,$50,$F6,$0F,$08);

Type
DiskParameterTableType = Record
StepRate, LoadTime, Shutoff,
BytesSec, SecTrack, GapLen,
DataLen, FGapLen, FillByte,
SettleTime,StartTime : byte;
End;

Var
AddressFields : array[1..MaxSectors] of AddressFieldType;
RAMTable : DiskParameterTableType absolute $0000:$0078;
regs : registers;

Begin
With Regs Do
Begin
AH := $18H; {set up to call function}
DL := DriveNum; {0 = A, 1 = B, etc.}
CH := NumOfTracks; {39 or 79 tracks}
CL := NumOfSectors; {number of sectors/track}
Intr($13,Regs); {call the BIOS}
if Flags and 1 = 0 the move(mem[ES:DI],RAMTable^,11)
else move(Disk360Params,RAMTable^,11);
End;
End;


Procedure LoadParameterTable;
Var
i : byte;
Begin
For i := 1 to NumSectors do
Begin
AddressFields[i].HeadNum := 0;
AddressFields[i].SectNum := i;
AddressFileds[i].SizeCode[i] := 2;
AddressFields[i + NumSectors].HeadNum := 1;
AddressFields[i + NumSectors].SectNum := i;
AddressFields[i + NumSectors].SizeCode := 2;
End;
End;

Function FormatTrack(Var Params; drive, track, sectors) : word;
var Regs : Registers;
i : byte;
Begin
With Regs Do
Begin
ES := seg(params);
BX := ofs(params);
AH := $05;
CH := track;
DL := drive;
DH := 0;
AL := sectors;
For i := 1 to sectors * 2 do Params[i].TrackNum := track;

Intr($13,Regs);
if Flags and 1 <> 0 then
begin
FormatTrack := word(AH);
exit;
end;
DH := 1;
ES := seg(params);
BX := ofs(params) + (4 * sectors);

AL := sectors
AH := 05H;
Intr($13,Regs);
if Flags and 1 = 0 then FormatTrack := 0
else FormatTrack := word(AH);
End;
End;


{$L BOOTSEC.BIN}

Procedure BootSector; External;

Type
BootType = Array[0..511] of byte;

Var
Boot : ^BootType;

Begin
Boot := @BootSector;
......
......

Const
Disk360Boot : Array[1..14] of byte =
($02,$01,$00,$02,$70,$00,$D0,$02,$FD,$02,$00,$09,$00,$02);

Function WriteSector(drive,track,side,
sector : byte; var buffer) : boolean;
Var
Regs : registers;
Begin
With Regs do
Begin
AH := $03;
AL := 1;
ES := seg(buffer);
BX := ofs(buffer);
CH := track;
CL := sector;
DH := side;
DL := drive;
Intr($13,Regs);
WriteSector := flags and 1 = 0;
End;
End;


Var

Fat : Array[2..3] of BootType;
i : byte;

Begin
FillChar(Fat,sizeof(Fat),0);
Fat[1] := $FD; Fat[2] := $FF; Fat[3] := $FF;

For i := 2 to 3 do
Begin
if not WriteSector(1,0,0,i,Fat) then;
if not WriteSector(1,0,0,i+2,Fat) then;
End;


Begin
FillChar(Boot,Sizeof(boot),0);
For i := 6 to 9 do if WriteSector(1,0,0,i,boot) then;
For i := 1 to 3 do if WriteSector(1,0,1,i,boot) then;
End;

Function VerifyTrack(Drive,Side,Track,Sectors : byte) : boolean;
Var Regs : Registers;
Begin
With Regs Do
Begin
AH := $04;
AL := Sectors;
CH := Track;
CL := 1;
DH := Side;
DL := Drive;
Int($13,Regs);
VerifyTrack := Flags and 1 = 0;
End;
End;

Function DosSector(Side,Track,BiosSector,SPS : byte) : word;
Begin
DosSector := word(BiosSector - 1) + word(Side * SPS) +
word(Track * SPS * 2);
End;

Function DosCluster(DosSector : word) : word;
Begin
DosCluster := (DosSector div SPC) - CNAdjust;
End;

Function FATOffset(Cluster : word) : word;
Begin
FATOffset := (Cluster * 3) div 2;
End;

Type
FATType = Array[1..512] of byte;

Var
FAT : array[0..4607] of byte;
FATSector : array[1..9] of FATType absolute FAT;
BadCount : word;

Procedure MarkFat(ClusterNumber : word);
Var Offset : word;
Begin
Inc(BadCount);
Offset := FATOffset(ClusterNumber);
if odd(ClusterNumber) then
Begin
Fat[Offset] := Fat[Offset] or $70;
Fat[Offset+1] := $FF;
End
Else
Begin
Fat[Offset] := $F7;
Fat[Offset+1] := $0F;
End;
End;

Procedure VerifyDisk(Drive,Tracks,Sectors,SPS,FatLen : byte);
Var Trk,Sector,Side : byte;
LastCN : word;

Procedure MarkTrack(Drive,Track,Side : byte);
Var Sector : byte
DosSect,Cluster : word;
Begin
For Sector := 1 to Sectors do
Begin
DosSec := DosSector(Side,Track,Sector,SPS);
Cluster := DosCluster(DosSec);
if Cluster <> LastCN then
Begin
MarkFat(Cluster);
LastCN := Cluster;
End;
End;
End;
End;

Begin
FillChar(Fat,Sizeof(Fat),0);
BadCount := 0;
LastCN := 0;
FAT[0] := $FD;
FAT[1] := $FF;
FAT[2] := $FF;
For Trk := 1 to Tracks do
Begin
For Side := 0 to 1 do
if not VerifyTrack(Drive,Trk,Side,SPS) then
MarkFat(Drive,Trk,Side);
End;
If BadCount > 0 then
Begin
For i := 2 to FatLen + 1 do
Begin
If WriteSector(Drive,0,0,i,FATSector[i]) then;
If WriteSecotr(Drive,0,0,i + FatLen,FATSector[i]) then;
End;
End;
End;