home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1991 / 06 / cgatr / cgapage.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1991-01-08  |  6.1 KB  |  190 lines

  1. (* ------------------------------------------------------ *)
  2. (*                     CGAPAGE.PAS                        *)
  3. (*       Acht Grafikseiten für Turbo 4.0/5.0              *)
  4. (*                                                        *)
  5. (* Die angegebenen Patches gelten für                     *)
  6. (* - Turbo-Pascal 4.0:                                    *)
  7. (*   CGA.BGI V1.00, 31. September 1987, 6029 Bytes Größe  *)
  8. (* - Turbo-Pascal 5.0:                                    *)
  9. (*   CGA.BGI V2.00, 21. März 1988, 6253 Bytes Größe       *)
  10. (* - Turbo-Pascal 5.5:                                    *)
  11. (*   CGA.BGI V2.00, 21. März 1988, 6253 Bytes Größe       *)
  12. (*                                                        *)
  13. (*       (c) 1991 Hanno-Ekkehard Müller & TOOLBOX         *)
  14. (* ------------------------------------------------------ *)
  15. UNIT CGAPage;
  16.  
  17. {$R-,S-}
  18.  
  19. INTERFACE
  20.  
  21. USES
  22.   Graph;
  23.  
  24.   PROCEDURE ClearPage(WhichPage : BYTE);
  25.   PROCEDURE UsePage(WhichPage : BYTE);
  26.   PROCEDURE ShowPage(WhichPage : BYTE);
  27.   PROCEDURE CopyPage(SourcePage, DestPage : BYTE);
  28.   PROCEDURE SwapPage(Page1, Page2 : BYTE);
  29.   PROCEDURE InitCGAPage(NPages : BYTE; Driver : Pointer);
  30.   PROCEDURE ReInitCGAPage;
  31.  
  32. IMPLEMENTATION
  33.  
  34. CONST
  35.   MaxPage             = 8;
  36.   MaxPageInUse : BYTE = 0;
  37.   CGASeg              = $B800; {CGA-Grafikspeicher-Segment }
  38.   PageLth             = $3F40; {8000+192+8000 = 16192 Bytes}
  39.   MemoryLth           = $3F50; {PageLth + 16 Bytes}
  40. {$IFDEF VER40}
  41.   Patch1              = $03F0; { CGA.BGI  V1.00 }
  42.   Patch2              = $059E;
  43. {$ELSE}
  44.   Patch1              = $04B0; { CGA.BGI  V2.00 }
  45.   Patch2              = $0668;
  46. {$ENDIF}
  47.  
  48. TYPE
  49.   TScreen = ARRAY [1..PageLth] OF BYTE;
  50.   PScreen = ^TScreen;
  51.  
  52. VAR
  53.   i          : INTEGER;
  54.   Memory     : ARRAY [1..MaxPage] OF pointer;
  55.      { 16 Bytes größerer Speicher pro Seite für den       }
  56.      { Segmentausgleich                                   }
  57.   Page       : ARRAY [0..MaxPage] OF ^TScreen;
  58.      { Page[0] zeigt auf den Grafikspeicher der CGA-Karte }
  59.   PageSeg    : ARRAY [0..MaxPage] OF WORD;
  60.      { Segment einer Grafikseite (Offset ist ja null)     }
  61.   BGICodeOfs,
  62.   BGICodeSeg : WORD;
  63.  
  64.  
  65.   PROCEDURE PatchDriver(ScrSeg : WORD);
  66.     { Patchen von CGA.BGI, das dank RegisterBGIDriver
  67.       im Speicher vorliegt }
  68.   BEGIN
  69.     MemW[BGICodeSeg:BGICodeOfs+Patch1] := ScrSeg;
  70.     MemW[BGICodeSeg:BGICodeOfs+Patch2] := ScrSeg;
  71.   END;
  72.  
  73.   PROCEDURE Fatal(n : INTEGER);
  74.     { Kleine Fehlerbehandlung um u.a. das Schreiben in
  75.       einen NIL-Pointer (= Systemcrash) zu verhindern }
  76.   BEGIN
  77.     RestoreCrtMode;
  78.     WriteLn('*** CGAPage-Fehler ***');
  79.     CASE n OF
  80.       1 : WriteLn('Zuwenig Speicherplatz.');
  81.       2 : WriteLn('CGAPage bereits initialisiert oder ',
  82.                   'zuviele Seiten.');
  83.       3 : WriteLn('Seite nicht initialisiert.');
  84.       4 : WriteLn('Unbekannte CGA-Treiber-Version.');
  85.     END;
  86.     Halt;
  87.   END;
  88.  
  89.   PROCEDURE ClearPage(WhichPage : BYTE);
  90.     { Löscht eine Seite schnell }
  91.   BEGIN
  92.     IF WhichPage > MaxPageInUse THEN Fatal(3);
  93.     FillChar(Page[WhichPage]^, PageLth, #0);
  94.   END;
  95.  
  96.   PROCEDURE UsePage(WhichPage : BYTE);
  97.     { Leitet die Grafikroutinen auf die Seite um }
  98.   BEGIN
  99.     IF WhichPage > MaxPageInUse THEN Fatal(3);
  100.     PatchDriver(PageSeg[WhichPage]);
  101.   END;
  102.  
  103.   PROCEDURE ShowPage(WhichPage : BYTE);
  104.     { Kopiert eine Seite in den CGA-Grafikspeicher }
  105.   BEGIN
  106.     IF WhichPage > MaxPageInUse THEN Fatal(3);
  107.     IF WhichPage > 0 THEN Page[0]^ := Page[WhichPage]^;
  108.   END;
  109.  
  110.   PROCEDURE CopyPage(SourcePage, DestPage : BYTE);
  111.     { Kopiert Seite Nr. SourcePage auf Nr. DestPage }
  112.   BEGIN
  113.     IF (SourcePage > MaxPageInUse) OR
  114.        (DestPage > MaxPageInUse) THEN Fatal(3);
  115.     Page[DestPage]^ := Page[SourcePage]^;
  116.   END;
  117.  
  118.   PROCEDURE SwapPage(Page1, Page2 : BYTE);
  119.     { Tauscht den Inhalt der beiden Seiten aus }
  120.   VAR
  121.     dummy : PScreen;
  122.   BEGIN
  123.     IF (Page1 > MaxPageInUse) OR (Page2 > MaxPageInUse) THEN
  124.       Fatal(3);
  125.     IF (MaxAvail < PageLth) THEN Fatal(1);
  126.     New(dummy);
  127.     dummy^ := Page[Page1]^;
  128.     Page[Page1]^ := Page[Page2]^;
  129.     Page[Page2]^ := dummy^;
  130.     Dispose(dummy);
  131.   END;
  132.  
  133.   PROCEDURE InitCGAPage(NPages : BYTE; Driver : Pointer);
  134.     { Initialisiert NPages Seiten }
  135.   VAR
  136.     i : BYTE;
  137.   BEGIN
  138.     IF (MaxPageInUse = 0) AND (NPages <= MaxPage) THEN BEGIN
  139.       BGICodeSeg := Seg(Driver^);
  140.       BGICodeOfs := Ofs(Driver^);
  141.         { Umrechnung auf minimalen Offset }
  142.       Inc(BGICodeSeg, BGICodeOfs DIV 16);
  143.       BGICodeOfs := BGICodeOfs MOD 16;
  144.         { Suche nach dem EOF-Zeichen,   }
  145.         { das auf die (c)-Meldung folgt }
  146.       i := 0;
  147.       WHILE Mem[BGICodeSeg:BGICodeOfs+i] <> $1A DO Inc(i);
  148.         { BGI-Code-Startadresse zum Offset addieren }
  149.       Inc(BGICodeOfs, MemW[BGICodeSeg:BGICodeOfs+i+1]);
  150.         { Erneutes Umrechnen auf minimalen Offset }
  151.       Inc(BGICodeSeg, BGICodeOfs DIV 16);
  152.       BGICodeOfs := BGICodeOfs MOD 16;
  153.         { Segment-Ausgleich von GRAPH "nachahmen" }
  154.       BGICodeOfs:=0;
  155.         { Falls Ihr Treiber andere Patchadressen besitzt }
  156.       IF (MemW[BGICodeSeg:BGICodeOfs+Patch1] <> CGASeg) OR
  157.          (MemW[BGICodeSeg:BGICodeOfs+Patch2] <> CGASeg) THEN
  158.          Fatal(4);
  159.         { Seite 0 ist der reale Grafikspeicher }
  160.       PageSeg[0] := CGASeg;
  161.       Page[0] := Ptr(CGASeg, $0000);
  162.       MaxPageInUse := NPages;
  163.       FOR i := 1 TO NPages DO BEGIN
  164.         IF MaxAvail < MemoryLth THEN
  165.           Fatal(1);     { Genug Speicher? }
  166.         GetMem(Memory[i], MemoryLth);
  167.           { Segment-Offset-Ausgleich }
  168.         PageSeg[i] := Seg(Memory[i]^) + 1;
  169.         Page[i] := Ptr(PageSeg[i], $0000);
  170.         ClearPage(i);
  171.       END;
  172.     END ELSE
  173.       { Falls InitCGAPage doppelt aufgerufen wird }
  174.       Fatal(2);
  175.   END;
  176.  
  177.   PROCEDURE ReInitCGAPage;
  178.     { Reinitialisierung }
  179.   VAR
  180.     i : BYTE;
  181.   BEGIN
  182.     PatchDriver(CGASeg);
  183.     FOR i := 1 TO MaxPageInUse DO
  184.       FreeMem(Memory[i], MemoryLth);
  185.     MaxPageInUse := 0;
  186.   END;
  187.  
  188. END.
  189. (* ------------------------------------------------------ *)
  190. (*               Ende von CGAPAGE.PAS                     *)