(* ================================================================ *)
(*       Prozeduren fr den Hercules-Grafikmodus (Kapitel 22)       *)
(*           (C) 1990 Matthias Uphoff & Addison Wesley              *)
(* ================================================================ *)

UNIT EVHerc;

INTERFACE

CONST MaxX = 719;                (* Maximale X-Koordinate *)
      MaxY = 347;                (* Maximale Y-Koordinate *)
      ScrSeg = $B000;            (* Bildspeicher-Segmentadresse *)

PROCEDURE WaitVRetraceHG;
   (* Fragt das Status Register ab, um auf den Beginn   *)
   (* der nchsten vertikalen Retrace-Periode zu warten *)
PROCEDURE InitHG;
   (* Initialisiert den Hercules-Grafikmodus *)
PROCEDURE ActiveHGPage(Page: Byte);
   (* Schaltet zwischen den Hercules-Grafikseiten 0 und 1 um *)
   (* Funktioniert nur im Full Mode                          *)
PROCEDURE PlotHG(x,y: Word; Color: Byte);
   (* Setzt im Hercules-Grafikmodus einen Punkt *)
   (* an der Position x,y in der Farbe Color    *)

(* ================================================================ *)

IMPLEMENTATION

VAR HGAddress: ARRAY[0..MaxY] OF Word;
    (* Array fr die Startadressen der Rasterzeilen *)

PROCEDURE WaitVRetraceHG;
(* ------------------------------------------------- *)
(* Fragt das Status Register ab, um auf den Beginn   *)
(* der nchsten vertikalen Retrace-Periode zu warten *)
(* ------------------------------------------------- *)
BEGIN
    (* Eventuell auf Ende der aktuellen Retrace-Periode warten *)
  REPEAT UNTIL (Port[$3BA] AND $80) <> 0;
    (* Auf den Beginn der nchsten Retrace-Periode warten *)
  REPEAT UNTIL (Port[$3BA] AND $80) = 0;
END;

PROCEDURE InitHG;
(* -------------------------------------- *)
(* Initialisiert den Hercules-Grafikmodus *)
(* -------------------------------------- *)
   CONST HGData: ARRAY[0..11] OF Byte =
       ($35,$2D,$2E,$07,$5B,$02,$57,$57,$02,$03,$00,$00);
   VAR i: Word;
       ModeReg: Byte ABSOLUTE $0000:$0465;
BEGIN
    (* Configuration Switch: Grafik erlauben, Half Mode *)
  Port[$3BF] := $01;
    (* Mode Control: Grafik ein, Bildschirm aus, Bildseite 0 *)
  Port[$3B8] := $02;
    (* Werte fr das Timing laden: *)
  FOR i := 0 TO 11 DO BEGIN
    Port[$3B4] := i;           (* Index *)
    Port[$3B5] := HGData[i];   (* Daten *)
  END;
    (* 32 KByte Bildspeicher lschen *)
  FillChar(Mem[$B000:$0000],$8000,0);
  WaitVRetraceHG;
    (* Mode Control: Grafik ein, Bildschirm ein, Bildseite 0 *)
  Port[$3B8] := $0A;
    (* Update der BIOS-Speicherstelle fr das Mode Control Register *)
  ModeReg := $0A;
  FOR i := 0 TO MaxY DO
    HGAddress[i] := (i AND 3) SHL 13 + (i SHR 2) * 90;
END;

PROCEDURE ActiveHGPage(Page: Byte);
(* ------------------------------------------------------ *)
(* Schaltet zwischen den Hercules-Grafikseiten 0 und 1 um *)
(* Funktioniert nur im Full Mode                          *)
(* ------------------------------------------------------ *)
  VAR ModeReg: Byte ABSOLUTE $0000:$0465;
BEGIN
  IF Page = 0 THEN                   (* Bit 7 lschen *)
    ModeReg := ModeReg AND NOT $80
  ELSE                               (* Bit 7 setzen *)
    ModeReg := ModeReg OR $80;
  WaitVRetraceHG;
  Port[$3B8] := ModeReg;
END;

PROCEDURE PlotHG(x,y: Word; Color: Byte);
(* ----------------------------------------- *)
(* Setzt im Hercules-Grafikmodus einen Punkt *)
(* an der Position x,y in der Farbe Color    *)
(* ----------------------------------------- *)
  VAR ScrOfs: Word;
      Bitmask: Byte;
BEGIN
  ScrOfs := HGAddress[y] + x SHR 3;
  Bitmask := $80 SHR (x AND 7);
  IF Color = 0 THEN                          (* Punkt schwarz *)
    Mem[ScrSeg:ScrOfs] := Mem[ScrSeg:ScrOfs] AND NOT Bitmask
  ELSE                                       (* Punkt hell *)
    Mem[ScrSeg:ScrOfs] := Mem[ScrSeg:ScrOfs] OR Bitmask;
END;

(* ================================================================ *)

BEGIN  (* Initialisierungsteil *)
END.

(* ================================================================ *)
