unit modexlib;                  {Header for modexlib.asm}
Interface
Var
  Vscreen:Pointer;              {pointer to source area for p13_2_modex}
  vpage:Word;                   {Offset of current invisible page}
  palette:Array[0..256*3-1] of Byte; {VGA - Palette}

  Procedure Init_ModeX;         {enable ModeX}
  Procedure Enter400;           {switch from Mode X to 400 lines}
  Procedure Double;             {virtual horiz. resolution of 640 on}

  Procedure P13_2_ModeX(start,pic_size:word);  {picture copied to Mode X screen}
  Procedure CopyScreen(Destination,Source:Word);  {Source page copied to destination page}
  Procedure Copy_Block(Destination,Source,Width,Height:Word);
                                {copies Block from source offset to destination}
  Procedure ClrX(pmask:byte);   {clear Mode X screen}

  Procedure Split(Row:Byte);    {Screen-Splitting in line row}
  Procedure Squeeze;            {squeeze picture from above and below}
  Procedure SetStart(t:Word);   {set start address of visible picture}
  Procedure Switch;             {switch back and forth between page 0 and 1}

  Procedure WaitRetrace;        {waits for vertical retrace}
  Procedure SetPal;             {copies palette to VGA-DAC}
  Procedure GetPal;             {reads out palette from VGA-DAC}

  Procedure Fade_Out;           {fades out picture}
  Procedure Fade_To(Destinationpal:Array of Byte; Step:Byte);
                                {fades from palette to Destinationpal}
  Procedure Pal_Rot(Start,Destination:Word);
                                {Rotates palette part by 1,
                                 if Start>Destination up, otherwise down}


{internal procedures:}
  Procedure Screen_Off;         {switches screen off}
  Procedure Screen_On;          {switches screen back on}
  Procedure CRTC_Unprotect;     {makes access to horizontal timing possible}
  Procedure CRTC_Protect;       {forbids access again}

  Procedure Init_Mode13;        {switches Mode 13h on}
  Procedure Show_Pic13;         {copies VScreen to Mode 13h}

  Procedure Make_bw(Var WorkPal:Array of Byte); {Palette to black/white}

Implementation
  Procedure Init_ModeX;external;
  Procedure Enter400;external;
  Procedure Double;external;

  Procedure P13_2_ModeX;external;
  Procedure CopyScreen;external;
  Procedure Copy_Block;external;
  Procedure ClrX;external;

  Procedure Split;external;
  Procedure Squeeze;external;
  Procedure SetStart;external;
  Procedure Switch;external;

  Procedure WaitRetrace;external;
  Procedure SetPal;external;
  Procedure GetPal;external;

  Procedure Fade_Out;external;
  Procedure Fade_To;external;
  Procedure Pal_Rot;external;
  {$l modexlib}

Procedure Screen_Off;
Begin
  Port[$3c4]:=1;                {select Register 1 of TS (TS Mode)}
  Port[$3c5]:=Port[$3c5] or 32; {set Bit 5 (Screen Off)}
End;
Procedure Screen_On;
Begin
  Port[$3c4]:=1;                {select Register 1 of TS (TS Mode)}
  Port[$3c5]:=Port[$3c5] and not 32;  {clear Bit 5 (Screen Off)}
End;
Procedure CRTC_UnProtect;
Begin
  Port[$3d4]:=$11;              {Register 11h of CRTC (Vertical Sync End)}
  Port[$3d5]:=Port[$3d5] and not $80  {clear Bit 7 (Protection Bit)}
End;
Procedure CRTC_Protect;
Begin
  Port[$3d4]:=$11;              {Register 11h of CRTC (Vertical Sync End)}
  Port[$3d5]:=Port[$3d5] or $80 {set Bit 7 (Protection Bit)}
End;
Procedure Init_Mode13;assembler;
asm
  mov ax,13h
  int 10h
End;
Procedure Show_Pic13;           {copies VScreen to Mode 13h}
Begin
  Move(Vscreen^,Ptr($a000,0)^,64000);
End;
Procedure Make_bw;              {reduce palette to black/white}
Var i,sum:Word;                 {valuation: 30% red, 59% green, 11% blue}
Begin
  For i:=0 to 255 do Begin
    Sum:=Round(WorkPal[i*3]*0.3 + WorkPal[i*3+1]*0.59 + WorkPal[i*3+2]*0.11);
    FillChar(WorkPal[i*3],3,Sum); {enter values}
  End;
End;

Begin
End.
