home *** CD-ROM | disk | FTP | other *** search
- (* ----------------------------------------------------------------------- *)
- (* CACHE.PAS *)
- (* Ein Platten-Cache-System fuer MS-DOS-kompatible in Turbo-Pascal *)
- (* ----------------------------------------------------------------------- *)
-
- PROGRAM Cache;
-
- {$K-}
- {$U-}
- {$R-}
- {$V-}
- {$I-}
- {$C-}
-
- {$I REGS8088.INC}
- {$I CRITICAL.INC}
- {$I MAKEINT.INC}
- {$I QUEUESET.INC}
- {$I COMPARE.INC}
-
- CONST
- DiskReset_ = $00;
- DiskStatus_ = $01;
- DiskReadSector_ = $02;
- DiskWriteSector_ = $03;
- DiskVerifySector_ = $04;
- DiskFormatTrack_ = $05;
- DiskFormatTrackBadSector_ = $06;
- DiskFormatDrive_ = $07;
- DiskDriveParameters_ = $08;
- DiskInit_ = $09;
- DiskReadLong_ = $0A;
- DiskWriteLong_ = $0B;
- DiskSeek_ = $0C;
- DiskAlternateReset_ = $0D;
- DiskReadSectorBuffer_ = $0E;
- DiskWriteSectorBuffer_ = $0F;
- DiskReady_ = $10;
- DiskRecalibrate_ = $11;
- DiskRamDiagnostic_ = $12;
- DiskDriveDiagnostic_ = $13;
- DiskControllerDiagnostic_ = $14;
-
- DiskOk_ = $00;
- DiskBadCommand_ = $01;
- DiskBadAddressMark_ = $02;
- DiskSectorNotFound_ = $04;
- DiskBadReset_ = $05;
- DiskInitFailed_ = $07;
- DiskDmaBoundary_ = $09;
- DiskBadTrack_ = $0B;
- DiskBadEcc_ = $10;
- DiskDataCorrected_ = $11;
- DiskBadController_ = $20;
- DiskBadSeek_ = $40;
- DiskTimeOut_ = $80;
- DiskUndefinedError_ = $BB;
- DiskSenseFailed_ = $FF;
-
- IntDisk = $13;
-
- CacheSize = 256;
- CacheSectorSize = 512;
- CacheCarry = $0001;
-
- TYPE
- CacheLocation_ = RECORD
- DriveNumber,
- HeadNumber : BYTE;
- CylinderNr : INTEGER;
- SectorNumber : BYTE;
- END;
-
- CacheSector_ = ARRAY [1..CacheSectorSize] OF BYTE;
- CacheSectorAddr_ = ^CacheSector_;
-
- CacheElement_ = RECORD
- Link : QuLink_;
- Location : CacheLocation_;
- Sector : CacheSector_;
- END;
-
- CacheElementAddr_ = ^CacheElement_;
-
- VAR
- CacheActive,
- CacheFree : QuHead_;
- CacheLocation : CacheLocation_;
- CacheBufferAddr : CacheSectorAddr_;
- CacheSectorCount : BYTE;
- CacheElement : CacheElementAddr_;
- CacheElementOld : CacheElementAddr_;
- (* ----------------------------------------------------------------------- *)
- FUNCTION
- CacheSearchElement (VAR Location: CacheLocation_) : CacheElementAddr_;
-
- VAR Element: CacheElementAddr_;
-
- BEGIN
- Element:= Addr (CacheActive.Next^);
- WHILE Element <> Addr (CacheActive) DO
- IF Equal(Element^.Location,Location,SizeOf(CacheLocation_)) THEN
- BEGIN CacheSearchElement:= Element; Exit; END
- ELSE
- Element:= Addr (Element^.Link.Next^);
- CacheSearchElement:= NIL;
- END;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE CacheBufferToSector (Location : CacheLocation_;
- SectorAddr : CacheSectorAddr_;
- SectorCount: BYTE);
-
- VAR I : INTEGER;
- Element : CacheElementAddr_;
-
- BEGIN
- WITH Location DO
- FOR I:= 1 TO SectorCount DO
- BEGIN
- Element:= CacheSearchElement (Location);
- IF Element = NIL THEN
- BEGIN
- IF QuEmpty(CacheFree) THEN
- Element:= Addr(CacheActive.Prev^)
- ELSE
- Element:= Addr (CacheFree.Prev^);
- Element^.Location:= Location;
- END;
- Move (SectorAddr^, Element^.Sector, CacheSectorSize);
- QuInto (CacheActive, Element^.Link);
- SectorAddr:=
- Ptr(Seg(SectorAddr^),Ofs(SectorAddr^)+CacheSectorSize);
- Location.SectorNumber:= Location.SectorNumber + 1;
- END;
- END;
- (* ----------------------------------------------------------------------- *)
- FUNCTION CacheSectorToBuffer (Location : CacheLocation_;
- SectorAddr : CacheSectorAddr_;
- SectorCount: BYTE) : BOOLEAN;
-
- VAR I : INTEGER;
- Element : CacheElementAddr_;
-
- BEGIN
- WITH Location DO
- FOR I:= 1 TO SectorCount DO
- BEGIN
- Element:= CacheSearchElement (Location);
- IF Element = NIL THEN
- BEGIN CacheSectorToBuffer:= FALSE; Exit; END
- ELSE
- Move (Element^.Sector, SectorAddr^, CacheSectorSize);
- QuInto (CacheActive, Element^.Link);
- SectorAddr:=
- Ptr(Seg(SectorAddr^),Ofs(SectorAddr^)+CacheSectorSize);
- Location.SectorNumber:= Location.SectorNumber + 1;
- END;
- CacheSectorToBuffer:= TRUE;
- END;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE CacheClearActive (DriveNumber: BYTE);
-
- VAR Element : CacheElementAddr_;
-
- BEGIN
- Element:= Addr (CacheActive.Next^);
- WHILE Element <> Addr (CacheActive) DO
- BEGIN
- IF Element^.Location.DriveNumber = DriveNumber THEN
- BEGIN
- Element:= Addr (Element^.Link.Next^);
- QuInto (CacheFree, Element^.Link.Prev^);
- END
- ELSE
- Element:= Addr (Element^.Link.Next^);
- END;
- END;
- (* ----------------------------------------------------------------------- *)
- CONST CacheOldInterrupt : IntEntry_ = (Offset:0; Segment:0);
- (* ----------------------------------------------------------------------- *)
- PROCEDURE CacheInterrupt;
-
- {$I BEGININT.INC}
- WITH PgmRegs DO
- BEGIN
- WITH CacheLocation DO
- BEGIN
- DriveNumber := PgmDl;
- HeadNumber := PgmDh;
- CylinderNr := PgmCh;
- SectorNumber:= PgmCl;
- CacheBufferAddr:= Ptr (PgmEs, PgmBx);
- CacheSectorCount:= PgmAl;
- CASE PgmAh OF
-
- DiskReadSector_ :
- BEGIN
- CacheElement:= NIL;
- IF DriveNumber < $80 THEN
- IF HeadNumber = 0 THEN
- IF CylinderNr = 0 THEN
- IF SectorNumber IN [2, 6] THEN
- BEGIN
- CacheElement:=
- CacheSearchElement(CacheLocation);
- IF CacheElement <> NIL THEN
- QuOut (CacheElement^.Link);
- END;
- IF NOT CacheSectorToBuffer
- (CacheLocation,CacheBufferAddr,CacheSectorCount)
- THEN
- BEGIN
- {$I CALLINT.INC}
- CacheOldInterrupt);
- {$I CALLINTE.INC};
- IF PgmAh = 0 THEN
- BEGIN
- PgmFlags:= PgmFlags AND (NOT CacheCarry);
- CacheBufferToSector (CacheLocation,
- CacheBufferAddr,
- CacheSectorCount);
- IF CacheElement <> NIL THEN
- BEGIN
- CacheElementOld:=
- CacheSearchElement (CacheLocation);
- IF NOT Equal(CacheElement^.Sector,
- CacheElementOld^.Sector,
- CacheSectorSize)
- THEN
- CacheClearActive (DriveNumber);
- END;
- END
- ELSE
- BEGIN
- PgmFlags:= PgmFlags OR CacheCarry;
- CacheClearActive (DriveNumber);
- END;
- END;
- IF CacheElement <> NIL THEN
- QuInto (CacheFree, CacheElement^.Link);
- END;
-
- DiskWriteSector_ :
- BEGIN
- CacheBufferToSector
- (CacheLocation, CacheBufferAddr, CacheSectorCount);
- {$I EXITINT.INC}
- CacheOldInterrupt);
- END;
-
- ELSE
- BEGIN
- CacheClearActive (DriveNumber);
- {$I EXITINT.INC}
- CacheOldInterrupt);
- END;
- END;
- END;
- END;
- {$I ENDINT.INC};
- (* ----------------------------------------------------------------------- *)
- PROCEDURE CacheInstall;
-
- VAR I : INTEGER;
- Element : ^CacheElement_;
-
- BEGIN
- QuInit (CacheActive);
- QuInit (CacheFree);
- FOR I:= 1 TO CacheSize DO
- BEGIN
- New (Element);
- IF Element <> NIL THEN
- BEGIN
- QuInit (Element^.Link);
- QuInto (CacheFree, Element^);
- END;
- END;
- WITH CacheOldInterrupt DO
- IntGet (IntDisk, Segment, Offset);
- IntSet (IntDisk, Cseg, Ofs (CacheInterrupt));
- END;
- (* ----------------------------------------------------------------------- *)
- BEGIN
- CacheInstall;
- WriteLn; WriteLn;
- WriteLn('Platten-Cache aktiv...');
- WriteLn('(C) 1987 W. Hofmeister-Dunkel & PASCAL INT.');
- WriteLn;
- MakeResident;
- END.
-