{ File: SG4.UTIL5.TEXT
  Contains routine for formatting floppy diskettes.


  COPYRIGHT (c) 1982, 1983 SAGE Computer Technology
  All Rights Reserved

}
PROCEDURE Format;
VAR
  accept:BOOLEAN;
  Drive:INTEGER;
  Left:BOOLEAN;
  ch:CHAR;
  FormatStatus:Conf_Floppy;
  OldStatus:Conf_Floppy;
  dummyboolean:BOOLEAN;
  
FUNCTION CheckDrive:BOOLEAN;
VAR
  done:BOOLEAN;
  N:INTEGER;
  Map:Conf_ChanTable;

BEGIN {CheckDrive}
  CheckDrive := FALSE;
  { Find drive }
  Conf_RD_ChanTable(Map);
  N:=0;
  Done:=FALSE;
  WHILE (NOT Done) AND (N < 32) DO
    BEGIN
      IF Map[N].Channel = Drive THEN
	BEGIN
	  Drive:=N;
	  Done:=TRUE;
	END
      ELSE
	N:=N+1;
    END;
  IF NOT Done THEN
    BEGIN
      WRITELN('Drive not equipped');
      EXIT(CheckDrive);
    END;
  Conf_RD_Floppy(Drive,OldStatus);
  IF OldStatus.Sides = 0 THEN
    BEGIN
      WRITELN('Drive not equipped');
      EXIT(CheckDrive);
    END;
  Conf_WT_Floppy(Drive,OldStatus);
  IF IORESULT <> 0 THEN
    BEGIN
      WRITELN('Cannot format under Multi-User');
      EXIT(CheckDrive);
    END;
  FormatStatus := OldStatus;
  CheckDrive := TRUE;
END;
  
PROCEDURE GenFormat;
VAR
  C,H,S:INTEGER;
  I,N:INTEGER;
  BLK:INTEGER;
  Skew:INTEGER;
  Stemp:INTEGER;
  Try:INTEGER;
  Done:BOOLEAN;
  Gap3R:INTEGER; {Gap3 for Reading back data}
  OldDTL:INTEGER;
  BlocksPerTrack:INTEGER;
  FormatErrors:INTEGER;
  FormData:ARRAY[1..18] OF 
	     PACKED RECORD
	       Head:0..255;
	       Cyl:0..255;
	       BPScode:0..255;
	       Sector:0..255;
	     END;
  DummyBuffer:ARRAY[0..2560] OF INTEGER;
  TempResult:INTEGER;

PROCEDURE VerifyDiskette;
BEGIN
  WRITELN;
  WRITELN;
  WRITE('Verification');
  BLK:=0;
  FOR C := 0 TO FormatStatus.Cylinders-1 DO
    FOR H := 0 TO FormatStatus.Sides-1 DO
      BEGIN
	IF ((C MOD 20) = 0) AND (H = 0) THEN WRITELN;
	WRITE('.');
	WITH FormatStatus DO
	  UNITREAD(Drive,DummyBuffer,SectorsPerTrack*BytesPerSector,BLK);
	IF IORESULT<>0 THEN
	  BEGIN
	    Exception(TRUE);
	    WRITELN;
	    WRITELN('Error while verifying Cylinder ',C:4,'  Head ',H);
	    Conf_WT_Floppy(Drive,OldStatus);
	    accept:=FALSE;
	    EXIT(GenFormat);
	  END;
	WITH FormatStatus DO
	  BLK:=BLK+((SectorsPerTrack*BytesPerSector) DIV 512);
      END;
  Conf_WT_Floppy(Drive,OldStatus);
  WRITELN;
  WRITE('Format Complete');
  IF FormatErrors = 0 THEN WRITELN
  ELSE
    WRITELN(' (',FormatErrors,')');
  WRITELN;
END;

BEGIN {GenFormat}
  MNU_ClrScreen;
  {
  N:=WhatFloppy(FormatStatus);
  WriteStandard(N);
  }
  WRITELN;
  WRITE('Is diskette ready for formatting in ');
  IF Left THEN WRITE('LEFT drive? ') ELSE WRITE('RIGHT drive? ');
  GetChar(ch);
  WRITELN;
  WRITELN;
  IF ch <> 'Y' THEN
    BEGIN
      WRITELN('Format aborted');
      EXIT(GenFormat);
    END;
  WITH FormatStatus DO
    BEGIN
      Gap3R:=Gap3;
      Gap3:=Gap3Format;
      OldDTL:=DataLeng;
      DataLeng:=PatternFormat;
    END;
  Conf_WT_Floppy(Drive,FormatStatus);
  UNITCLEAR(Drive);
  WRITE('Formatting');
  Skew:=0;
  BlocksPerTrack:=FormatStatus.BytesPerSector*FormatStatus.SectorsPerTrack
		  DIV 512;
  FormatErrors:=0;
  FOR C := 0 TO FormatStatus.Cylinders-1 DO
    BEGIN
      FOR H := 0 TO FormatStatus.Sides-1 DO
	BEGIN
	  FOR S := 1 TO FormatStatus.SectorsPerTrack DO
	    WITH FormData[S] DO
	      BEGIN
		Cyl := C;
		Head := H;
		IF FormatStatus.IBMflag AND (H=1) THEN
		  BEGIN
		    Stemp:=S+Skew;
		    IF Stemp > FormatStatus.SectorsPerTrack THEN
		      Stemp:=Stemp-FormatStatus.SectorsPerTrack;
		  END
		ELSE
		  BEGIN
		    Stemp:=S-Skew;
		    IF Stemp <= 0 THEN
		      Stemp:=Stemp+FormatStatus.SectorsPerTrack;
		  END;
		IF FormatStatus.NCIflag THEN
		  IF (C<>0) OR (H<>0) OR (Stemp<>1) THEN Stemp:=Stemp+8;
		Sector := Stemp;
		IF FormatStatus.BytesPerSector=512 THEN BPScode := 2
		ELSE
		  BPScode:=1;
	      END;
	    IF ((C MOD 20) = 0) AND (H = 0) THEN WRITELN;
	    WRITE('.');
	  Try:=0;
	  Done:=FALSE;
	  REPEAT
	    Try:=Try+1;
	    UNITWRITE(Drive,FormData,FormatStatus.SectorsPerTrack*4,(C*256)+H,
		      8192 {Format bit});
	    IF (IORESULT<>0) THEN
	      BEGIN
		FormatErrors:=FormatErrors+1;
		IF Try>=3 THEN
		  BEGIN
		    TempResult:=IORESULT;
		    Exception(TRUE);
		    WRITELN;
		    WRITELN('Error ',TempResult,
			    ' while formatting Cylinder ',C:4,'	 Head ',H);
		    Conf_WT_Floppy(Drive,OldStatus);
		    accept:=FALSE;
		    EXIT(GenFormat);
		  END;
	      END
	    ELSE
	      BEGIN
		IF FormatStatus.IBMflag THEN
		  BEGIN
		    IF H = 0 THEN
		      BLK:=C*BlocksPerTrack
		    ELSE
		      BLK:=((2*FormatStatus.Cylinders)-C-1)*BlocksPerTrack;
		  END
		ELSE
		  BLK:=((FormatStatus.Sides*C)+H)*BlocksPerTrack;
		UNITREAD(Drive,DummyBuffer,FormatStatus.SectorsPerTrack *
			 FormatStatus.BytesPerSector,BLK);
		IF IORESULT <> 0 THEN
		  BEGIN
		    FormatErrors:=FormatErrors+1;
		    IF Try>=3 THEN
		      BEGIN
			TempResult:=IORESULT;
			Exception(TRUE);
			WRITELN;
			WRITELN('Error ',TempResult,
				' while checking Cylinder ',C:4,' Head ',H);
			Conf_WT_Floppy(Drive,OldStatus);
			accept:=FALSE;
			EXIT(GenFormat);
		      END;
		  END
		ELSE
		  Done:=TRUE;
	      END;
	  UNTIL Done;
	END;
      Skew:=Skew+FormatStatus.Skew;
      IF Skew>FormatStatus.SectorsPerTrack THEN
	Skew:=Skew-FormatStatus.SectorsPerTrack;
    END;
  FormatStatus.Gap3:=Gap3R;
  FormatStatus.Tries:=1;
  FormatStatus.DataLeng:=OldDTL;
  Conf_WT_Floppy(Drive,FormatStatus);
  VerifyDiskette;
END;
  
BEGIN {Format}
  accept := false;
  REPEAT
    MNU_ClrScreen;
    WRITELN('Floppy Diskette Formatter');
    WRITELN;
    WRITE('Drive to be formatted - L(eft or R(ight ? ');
    GetChar(ch);
    WRITELN;
    WRITELN;
    IF (ch='4') OR (ch='L') OR (Ch='l') THEN
      BEGIN
	Drive := 4;
	Left:=TRUE;
	accept:= TRUE;
      END
    ELSE
      IF (ch='5') OR (ch='R') OR (ch='r') THEN
	BEGIN
	  Drive := 5;
	  Left:=FALSE;
	  accept:= TRUE;
	END
      ELSE
	IF ch<>'Q' THEN WRITE(CHR(7))
	ELSE
	  EXIT(Format);
    IF accept THEN accept := CheckDrive;
    IF accept THEN GenFormat;
    IF NOT accept THEN dummyboolean:=sc_space_wait(FALSE);
    WHILE accept DO
      BEGIN
	WRITELN;
	WRITE('More diskettes to format? ');
	GetChar(ch);
	IF ch='Y' THEN
	  BEGIN
	    GenFormat;
	  END
	ELSE
	  BEGIN
	    WRITELN;
	    EXIT(Format);
	  END;
	IF NOT accept THEN dummyboolean:=sc_space_wait(FALSE);
      END;
  UNTIL accept;
END;

                        