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

{
  If  you are ready to delve into pure VGA-register programming, you can
  realize  graphic  modes  up  to  400x600x256 pixels on any vanilla-VGA
  card;  watch  out  for  TWEAK*.*  for a cute tool to create such modes
  yourself easily.

  Here's  a  small example for a 360x256x256 mode, give it a try on your
  system:
}

{Purpose  : Demonstrate 360x256x256 graphics resolution              }
{Author   : Kai Rohrbacher, kai.rohrbacher@logo.ka.sub.org           }
{Language : TurboPascal 6.0   }
{Date     : 17.07.1994        }
{Remarks  : Register set generated with Robert Schmidt's TWEAK1.6beta}
{           adopted to Pascal by myself. No guarantees, use on your  }
{           own risk!}
{           If you directly want to play around with Bob's TWEAK,    }
{           here is the original register file:
begin 644 360x256b.256
MP@,`Y]0#`&O4`P%9U`,"6M0#`X[4`P1>U`,%BM0#!B/4`P>RU`,(`-0#"6'4
M`Q`*U`,1K-0#$O_4`Q,MU`,4`-0#%0?4`Q8:U`,7X\0#`0'$`P0&S@,%0,X#
*!@7``Q!!P`,3````
`
end
}

USES Dos;
CONST ATTRCON_ADDR = $3c0;
      MISC_ADDR = $3c2;
      VGAENABLE_ADDR = $3c3;
      SEQ_ADDR = $3c4;
      GRACON_ADDR = $3ce;
      CRTC_ADDR = $3d4;
      STATUS_ADDR = $3da;

TYPE Register=RECORD
      prt:WORD;
      index:BYTE;
      value:BYTE
     END;
    RegisterPtr=^Register;
CONST Mode360x256: ARRAY[0..24] OF Register =
 (
  ( prt:$3c2; index:$0; value:$e7),
  ( prt:$3d4; index:$0; value:$6b),
  ( prt:$3d4; index:$1; value:$59),
  ( prt:$3d4; index:$2; value:$5a),
  ( prt:$3d4; index:$3; value:$8e),
  ( prt:$3d4; index:$4; value:$5e),
  ( prt:$3d4; index:$5; value:$8a),
  ( prt:$3d4; index:$6; value:$23),
  ( prt:$3d4; index:$7; value:$b2),
  ( prt:$3d4; index:$8; value:$0),
  ( prt:$3d4; index:$9; value:$61),
  ( prt:$3d4; index:$10; value:$a),
  ( prt:$3d4; index:$11; value:$ac),
  ( prt:$3d4; index:$12; value:$ff),
  ( prt:$3d4; index:$13; value:$2d),
  ( prt:$3d4; index:$14; value:$0),
  ( prt:$3d4; index:$15; value:$7),
  ( prt:$3d4; index:$16; value:$1a),
  ( prt:$3d4; index:$17; value:$e3),
  ( prt:$3c4; index:$1; value:$1),
  ( prt:$3c4; index:$4; value:$6),
  ( prt:$3ce; index:$5; value:$40),
  ( prt:$3ce; index:$6; value:$5),
  ( prt:$3c0; index:$10; value:$41),
  ( prt:$3c0; index:$13; value:$0)
 );

{
   readyVgaRegs() does the initialization to make the VGA ready to
  accept any combination of configuration register settings.

  This involves enabling writes to index 0 to 7 of the CRT controller
  (port $3d4), by clearing the most significant bit (bit 7) of index
  $11.
}

PROCEDURE readyVgaRegs;
VAR v:INTEGER;
BEGIN
  port[$3d4]:=$11;
  v:=port[$3d5] AND $7f;
  port[$3d4]:=$11;
  port[$3d5]:=v;
END;

{
  outReg sets a single register according to the contents of the
  passed Register structure.
}
PROCEDURE outReg(r:Register);
VAR dummy:BYTE;
BEGIN
 IF r.prt=ATTRCON_ADDR
  THEN BEGIN
        dummy:=port[STATUS_ADDR];     { reset read/write flip-flop }
        port[ATTRCON_ADDR]:= r.index OR $20; { ensure VGA output is enabled }
        port[ATTRCON_ADDR]:= r.value;
       END
 ELSE IF (r.prt=MISC_ADDR) OR (r.prt=VGAENABLE_ADDR)
  THEN port[r.prt]:=r.value   {  directly to the port }
 ELSE BEGIN
       port[r.prt]:=r.index;  {  index to port        }
       port[r.prt+1]:=r.value;{  value to port+1        }
      END;
END;

{
  outRegArray sets n registers according to the array pointed to by r.
  First, indexes 0-7 of the CRT controller are enabled for writing.
}
PROCEDURE outRegArray(r:RegisterPtr; n:INTEGER);
BEGIN
 readyVgaRegs;
 WHILE n>0 DO
  BEGIN
   DEC(n);
   outReg(r^);
   ASM
    LES DI,r
    ADD DI,TYPE Register
    MOV WORD PTR [r],DI
   END;
  END;
END;



VAR y,lastMode:INTEGER;
    regs:REGISTERS;
BEGIN
 {Save old BIOS mode}
 regs.AH := $0f; INTR($10,regs); lastMode := regs.AL;

 {Set mode 13h to make sure the EGA palette set is correct for a }
 {256color mode}
 regs.AX := $13; INTR($10,regs);

  { Note that no initialization is neccessary now.  The Register array
      is linked in as global data, and is directly accessible.  Take
      note of the way the number of Register elements in the array is
     calculated: }

 outRegArray(@Mode360x256, sizeof(Mode360x256) DIV sizeof(Register));
 portw[$3c4]:=$0f02; { Enable all 4 planes }

  { Fill the screen with a blend of red and blue lines, defining the
     palette on the fly. }

  port[$3c8]:=0;         { start with color 0 }
  FOR y:=0 TO 255 DO
   BEGIN
    port[$3c9]:= y SHR 2;        { red component }
    port[$3c9]:= 0;              { green component }
    port[$3c9]:= (256-y) SHR 2;  { blue component }
    FillChar(Mem[SegA000:y*90],90,y);
   END;

 y:=0;
 WHILE y<256 DO
  BEGIN
   MEM[SegA000:y*90]:=255;
   inc(y,8)
  END;
  readln;

  { The picture is drawn, so wait for user to get tired of it. }

  { Restore the saved mode number.  Borland's textmode() won't work, as the
      C library still thinks we're in the mode it detected at startup.
     The palette will be set to the BIOS mode's default. }

  regs.AX := lastMode; INTR($10,regs);

END.

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