[Back to GRAPHICS SWAG index]  [Back to Main SWAG index]  [Original]


{ Illustration on how VGA Write Mode 1 works }
{ by Andrew Golovin (2:5080/10@Fidonet)      }
{ Can be used at your own risk freely w/o    }
{ any charge                                 }
{============================================}
{ PREFACE:                                   }
{ This example illustrate posibility to save }
{ Bitmaps in unused VRam. And use VWM1 to    }
{ restore it by 4 pixels at one byte         }
{ Use arrows to move "bitmap" on screen.     }
{ This example _only_ illustrate this mode   }
{ Extremly needs optimization! Don't use it  }
{ as is. Just an idea.                       }

Uses CRT;
var
  OldMode: Byte;

procedure SetWriteMode(Wmode: Byte); assembler;
asm
  Mov     DX,3ceh
  Mov     AL,5
  Out     DX,AL
  Inc     DX
  In      AL,DX
  And     AL,11111100b
  Or      AL,WMode
  Out     DX,AL
end;

procedure Init320x200_X; assembler;
asm
  Mov AH,0fh; Int 10h; Mov [OldMode],al; Mov AX,13h; Int 10h;
  Mov DX,3c4h; Mov AL,04h; Out DX,AL; Inc DX; In AL,DX; And AL,011110111b;
  Or AL,000000100b; Out DX,AL; Dec DX; Mov AX,0f02h; Out DX,AX;
  Mov AX,0a000h; Mov ES,AX; XOr DI,DI; Mov AX,0202h; Mov CX,8000h;
  ClD; RepNZ StoSW; Mov DX,3d4h; Mov AL,14h; Out DX,AL; Inc DX;
  In AL,DX; And AL,010111111b; Out DX,AL; Dec DX; Mov AL,017h;
  Out DX,AL; Inc DX; In AL,DX; Or AL,01000000b; Out DX,AL; Mov DX,3d4h;
  Mov AX,80; ShR AX,1; Mov AH,AL; Mov AL,13h; Out DX,AX; Ret
end;

Procedure PutPixel(x,y: Word; c: Byte);
  begin
    asm
      Mov    DX,3c4h
      Mov    AL,02
      Out    DX,AL
      Mov    AX,Y
      ShL    AX,4
      Mov    DI,AX
      ShL    AX,2
      Add    DI,AX
      Mov    AX,X
      ShR    AX,2
      Add    DI,AX
      Mov    AX,X
      And    AX,3
      Mov    CL,AL
      Mov    AL,1
      ShL    AL,CL
      Inc    DX
      Out    DX,AL
      Mov    AX,0a000h
      Mov    ES,AX
      Mov    AL,C
      StoSB
    end;
  end;

procedure MaskBits(BitsToMask: Byte); assembler;
  asm
    Mov     DX,3ceh
    Mov     AL,8
    Mov     AH,BitsToMask
    Out     DX,AX
  end;

Procedure MaskPlanes(PlaneToMask: Byte); assembler;
asm
  Mov     DX,3c4h
  Mov     AL,2
  Out     DX,AL
  Inc     DX
  Mov     AL,PlaneToMask
  Out     DX,AL
End;

Procedure StoreBack(x,y,w,h: word; toAddr: word);
  var
    curx,cury: Word;
  begin
    SetWriteMode(1);
    MaskPlanes($f);
    MaskBits($ff);
    For CurY:=Y to Y+H do
      Move(Mem[$a000:CurY*80+x],Mem[$a000:toAddr+(CurY-Y)*W],w);
    SetWriteMode(0);
  end;

Procedure RestoreBack(x,y,w,h: word; fromAddr: Word);
  var
    cury,curx: Word;
  begin
    SetWriteMode(1);
    MaskPlanes($f);
    MaskBits($ff);
    For CurY:=Y to Y+H do
      Move(Mem[$a000:fromAddr+(CurY-Y)*W],Mem[$a000:CurY*80+x],w);
    SetWriteMode(0);
  end;

var
  x,y: Word;
  curx,cury: Word;
  c: Char;
Begin
  Init320x200_x;
  For x:=0 to 319 do
    For y:=0 to 199 do
      PutPixel(x,y,(x +y) mod 16+16);
  StoreBack(0,0,3,12,16000);
  For x:=0 to 11 do
    For y:=0 to 11 do
      PutPixel(x,y,Random(255));
  StoreBack(0,0,3,12,16200);
  CurX:=0;CurY:=0;
  Repeat
    Repeat Until KeyPressed;
    c:=ReadKey;
    If c=#0
       then
         begin
           RestoreBack(CurX,CurY,3,12,16000);
           c:=ReadKey;
           Case c of
             #80: If CurY<187
                     then
                       Inc(CurY);
             #72: If CurY>0
                     Then
                       Dec(CurY);
             #75: If CurX>0
                     Then
                       Dec(CurX);
             #77: If CurX<77
                     Then
                       Inc(CurX);
           end;
           StoreBack(CurX,CurY,3,12,16000);
           RestoreBack(CurX,CurY,3,12,16200);
         end;
  Until c=#27;
  asm Mov al,OldMode; XOr AH,AH; Int 10h end;
End.


[Back to GRAPHICS SWAG index]  [Back to Main SWAG index]  [Original]