{XMSEXAM.PAS / EXAMPLE FOR SIMPLE ANIMATION }
{WRITING BY THE KING IN 01/02/96            }
Uses Crt,KmagUnit;
Const
Image: Array[1..24*5] of byte=(15,0,0,15,0,15,15,15,15,0,15,0,0,0,0,15,0,0,0,0,15,15,15,15,
                              15,0,0,15,0,15,0,0,0,0,15,0,0,0,0,15,0,0,0,0,15,0,0,15,
                              15,15,15,15,0,15,15,15,15,0,15,0,0,0,0,15,0,0,0,0,15,0,0,15,
                              15,0,0,15,0,15,0,0,0,0,15,0,0,0,0,15,0,0,0,0,15,0,0,15,
                              15,0,0,15,0,15,15,15,15,0,15,15,15,15,0,15,15,15,15,0,15,15,15,15);
Type

    {This Is The Virtual Screen Type}
    VirtualScreenType = Array[0..64000] Of Byte;
    VirtualScreenTypeP = ^VirtualScreenType;

Var
    Virtual_Screen ,
    Virtual_Screen1 : VirtualScreenTypeP; {Two Virtual Screens.}

{------------------------------------------------}
{Put A Pixel On Any Kind Of Page.                }
{------------------------------------------------}

Procedure PutPixel(X,Y:Integer;Col:Byte;Var Where);Assembler;
Asm
    Mov Ax,Word(Where+2) {Ax = Where[2](Segment)}
    Mov Es,AX         {Es = Segment Of The Screen}
    Mov Ax,Y          {Ax = Y}
    Mov Bx,Ax         {Bx = Y}
    Shl Ax,8          {Ax = Ax * 256}
    Shl Bx,6          {Bx = Bx * 64}
    Add Ax,Bx         {Ax = (256*64=320))}
    Add Ax,x          {Ax = Vline + Hline = Offset}
    Mov Di,Ax         {Di = Offset}
    Mov Al,Col        {Al = Color}
    StoSb             {[0A000h:Offset] = Color}
End;

Procedure ShowVirtualScreen(Var VScreen);Assembler;
Asm
    Push Ds                 {Saving Ds}
    Mov Ax,Word(Vscreen+2)  {Ax = Segment Vscreen}
    Mov Ds,Ax               {Ds = Ax}
    Mov Ax,0A000h           {Ax = Screen Segment}
    Mov Es,AX               {Es = Ax}
    Xor Di,Di               {Di = 0}
    Xor Si,Si               {Si = 0}
    Mov Cx,32000            {Cx = 32000}
    Rep MovSw               {Move 32000*2 Bytes}
                            {From [Ds:Si],[Es:Di]}
    Pop Ds                  {Restore Ds}
END;
{-----------------------------------}
{            Flip Pages             }
{-----------------------------------}
Procedure FlipScreens(Var Vfrom,Vto);Assembler;
Asm
   Push Ds               {Save Ds}
   Mov Ax,Word(Vfrom+2)  {Ax = Segment Vfrom}
   Mov Ds,Ax             {Ds = Ax}
   Mov Ax,Word(Vto+2)    {Ax = Segment Vto}
   MOv Es,AX             {Es = Ax}
   Xor Di,Di             {Di = 0}
   Xor Si,Si             {Si = 0}
   Mov Cx,32000          {Cx = 32000}
   Rep MovSw             {Move 32000*2 Bytes}
                         {From [Ds:Si],[Es:Di]}
   Pop Ds                {Restore Ds}
END;
{----------------}
{Paint The BitMap}
{----------------}
Procedure Paint_BitMap(X,Y:Integer);
Var
    T,T1:Byte;
Begin
    For T:=0 To 4 Do
    Begin
        For T1:=1 To 24 Do
        Begin
            If Image[T*24+T1] <> 0 Then
                PutPixel(X+T1,Y+T,Image[T*24+T1],Virtual_Screen^);
        End;
    End;
End;

Var X,Y:Integer;
    T : Word;
    Ran : Integer;
Begin
    New(Virtual_Screen);
    New(Virtual_Screen1);
    Randomize;
    FillChar(Virtual_Screen^,64000,0);
    For T:=1 To 65000 Do
        PutPixel(Random(320),Random(200),Random(255),Virtual_Screen^);
    FlipScreens(Virtual_Screen^,Virtual_Screen1^);
    SetMode;
    T:=0;
    X:=160;
    Y:=100;
    Repeat
        Ran := Random(3)-1;
        If X + Ran >= 320-24 Then Ran := 0;
        If X + Ran <= 0 Then Ran := 0;
        X := X + Ran;
        Ran := Random(3)-1;
        If Y + Ran >= 200-5 Then Ran :=0;
        If Y + Ran <= 0 Then Ran := 0;
        Y := Y + Ran;

        Paint_BitMap(X,Y);
        ShowVirtualScreen(Virtual_Screen^);
        FlipScreens(Virtual_Screen1^,Virtual_Screen^);
    Until(KeyPressed);
    Dispose(Virtual_Screen);
    Dispose(Virtual_Screen1);
    SetTextMode;
End.