[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]