home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* CGAPAGE.PAS *)
- (* Acht Grafikseiten für Turbo 4.0/5.0 *)
- (* *)
- (* Die angegebenen Patches gelten für *)
- (* - Turbo-Pascal 4.0: *)
- (* CGA.BGI V1.00, 31. September 1987, 6029 Bytes Größe *)
- (* - Turbo-Pascal 5.0: *)
- (* CGA.BGI V2.00, 21. März 1988, 6253 Bytes Größe *)
- (* - Turbo-Pascal 5.5: *)
- (* CGA.BGI V2.00, 21. März 1988, 6253 Bytes Größe *)
- (* *)
- (* (c) 1991 Hanno-Ekkehard Müller & TOOLBOX *)
- (* ------------------------------------------------------ *)
- UNIT CGAPage;
-
- {$R-,S-}
-
- INTERFACE
-
- USES
- Graph;
-
- PROCEDURE ClearPage(WhichPage : BYTE);
- PROCEDURE UsePage(WhichPage : BYTE);
- PROCEDURE ShowPage(WhichPage : BYTE);
- PROCEDURE CopyPage(SourcePage, DestPage : BYTE);
- PROCEDURE SwapPage(Page1, Page2 : BYTE);
- PROCEDURE InitCGAPage(NPages : BYTE; Driver : Pointer);
- PROCEDURE ReInitCGAPage;
-
- IMPLEMENTATION
-
- CONST
- MaxPage = 8;
- MaxPageInUse : BYTE = 0;
- CGASeg = $B800; {CGA-Grafikspeicher-Segment }
- PageLth = $3F40; {8000+192+8000 = 16192 Bytes}
- MemoryLth = $3F50; {PageLth + 16 Bytes}
- {$IFDEF VER40}
- Patch1 = $03F0; { CGA.BGI V1.00 }
- Patch2 = $059E;
- {$ELSE}
- Patch1 = $04B0; { CGA.BGI V2.00 }
- Patch2 = $0668;
- {$ENDIF}
-
- TYPE
- TScreen = ARRAY [1..PageLth] OF BYTE;
- PScreen = ^TScreen;
-
- VAR
- i : INTEGER;
- Memory : ARRAY [1..MaxPage] OF pointer;
- { 16 Bytes größerer Speicher pro Seite für den }
- { Segmentausgleich }
- Page : ARRAY [0..MaxPage] OF ^TScreen;
- { Page[0] zeigt auf den Grafikspeicher der CGA-Karte }
- PageSeg : ARRAY [0..MaxPage] OF WORD;
- { Segment einer Grafikseite (Offset ist ja null) }
- BGICodeOfs,
- BGICodeSeg : WORD;
-
-
- PROCEDURE PatchDriver(ScrSeg : WORD);
- { Patchen von CGA.BGI, das dank RegisterBGIDriver
- im Speicher vorliegt }
- BEGIN
- MemW[BGICodeSeg:BGICodeOfs+Patch1] := ScrSeg;
- MemW[BGICodeSeg:BGICodeOfs+Patch2] := ScrSeg;
- END;
-
- PROCEDURE Fatal(n : INTEGER);
- { Kleine Fehlerbehandlung um u.a. das Schreiben in
- einen NIL-Pointer (= Systemcrash) zu verhindern }
- BEGIN
- RestoreCrtMode;
- WriteLn('*** CGAPage-Fehler ***');
- CASE n OF
- 1 : WriteLn('Zuwenig Speicherplatz.');
- 2 : WriteLn('CGAPage bereits initialisiert oder ',
- 'zuviele Seiten.');
- 3 : WriteLn('Seite nicht initialisiert.');
- 4 : WriteLn('Unbekannte CGA-Treiber-Version.');
- END;
- Halt;
- END;
-
- PROCEDURE ClearPage(WhichPage : BYTE);
- { Löscht eine Seite schnell }
- BEGIN
- IF WhichPage > MaxPageInUse THEN Fatal(3);
- FillChar(Page[WhichPage]^, PageLth, #0);
- END;
-
- PROCEDURE UsePage(WhichPage : BYTE);
- { Leitet die Grafikroutinen auf die Seite um }
- BEGIN
- IF WhichPage > MaxPageInUse THEN Fatal(3);
- PatchDriver(PageSeg[WhichPage]);
- END;
-
- PROCEDURE ShowPage(WhichPage : BYTE);
- { Kopiert eine Seite in den CGA-Grafikspeicher }
- BEGIN
- IF WhichPage > MaxPageInUse THEN Fatal(3);
- IF WhichPage > 0 THEN Page[0]^ := Page[WhichPage]^;
- END;
-
- PROCEDURE CopyPage(SourcePage, DestPage : BYTE);
- { Kopiert Seite Nr. SourcePage auf Nr. DestPage }
- BEGIN
- IF (SourcePage > MaxPageInUse) OR
- (DestPage > MaxPageInUse) THEN Fatal(3);
- Page[DestPage]^ := Page[SourcePage]^;
- END;
-
- PROCEDURE SwapPage(Page1, Page2 : BYTE);
- { Tauscht den Inhalt der beiden Seiten aus }
- VAR
- dummy : PScreen;
- BEGIN
- IF (Page1 > MaxPageInUse) OR (Page2 > MaxPageInUse) THEN
- Fatal(3);
- IF (MaxAvail < PageLth) THEN Fatal(1);
- New(dummy);
- dummy^ := Page[Page1]^;
- Page[Page1]^ := Page[Page2]^;
- Page[Page2]^ := dummy^;
- Dispose(dummy);
- END;
-
- PROCEDURE InitCGAPage(NPages : BYTE; Driver : Pointer);
- { Initialisiert NPages Seiten }
- VAR
- i : BYTE;
- BEGIN
- IF (MaxPageInUse = 0) AND (NPages <= MaxPage) THEN BEGIN
- BGICodeSeg := Seg(Driver^);
- BGICodeOfs := Ofs(Driver^);
- { Umrechnung auf minimalen Offset }
- Inc(BGICodeSeg, BGICodeOfs DIV 16);
- BGICodeOfs := BGICodeOfs MOD 16;
- { Suche nach dem EOF-Zeichen, }
- { das auf die (c)-Meldung folgt }
- i := 0;
- WHILE Mem[BGICodeSeg:BGICodeOfs+i] <> $1A DO Inc(i);
- { BGI-Code-Startadresse zum Offset addieren }
- Inc(BGICodeOfs, MemW[BGICodeSeg:BGICodeOfs+i+1]);
- { Erneutes Umrechnen auf minimalen Offset }
- Inc(BGICodeSeg, BGICodeOfs DIV 16);
- BGICodeOfs := BGICodeOfs MOD 16;
- { Segment-Ausgleich von GRAPH "nachahmen" }
- BGICodeOfs:=0;
- { Falls Ihr Treiber andere Patchadressen besitzt }
- IF (MemW[BGICodeSeg:BGICodeOfs+Patch1] <> CGASeg) OR
- (MemW[BGICodeSeg:BGICodeOfs+Patch2] <> CGASeg) THEN
- Fatal(4);
- { Seite 0 ist der reale Grafikspeicher }
- PageSeg[0] := CGASeg;
- Page[0] := Ptr(CGASeg, $0000);
- MaxPageInUse := NPages;
- FOR i := 1 TO NPages DO BEGIN
- IF MaxAvail < MemoryLth THEN
- Fatal(1); { Genug Speicher? }
- GetMem(Memory[i], MemoryLth);
- { Segment-Offset-Ausgleich }
- PageSeg[i] := Seg(Memory[i]^) + 1;
- Page[i] := Ptr(PageSeg[i], $0000);
- ClearPage(i);
- END;
- END ELSE
- { Falls InitCGAPage doppelt aufgerufen wird }
- Fatal(2);
- END;
-
- PROCEDURE ReInitCGAPage;
- { Reinitialisierung }
- VAR
- i : BYTE;
- BEGIN
- PatchDriver(CGASeg);
- FOR i := 1 TO MaxPageInUse DO
- FreeMem(Memory[i], MemoryLth);
- MaxPageInUse := 0;
- END;
-
- END.
- (* ------------------------------------------------------ *)
- (* Ende von CGAPAGE.PAS *)