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

{
> Attention: All those who are familiar with graphics ports
> (ie. Sean Palmer, Jan Doggen, and others I don't yet know).

Don't consider myself that familiar with 'em, but here are some
snippets and remarks. BTW I consider phasing out all BGI stuff in my
code in the first half of '93 or so, which will be a major effort.
After that, I'll rank myself among the register-twiddlers. Maybe we
should team up on this project if you plan on going in that direction
too.

> Would you mind explaining the EGA map mask (?) and
> sequencer (?) register ports (I don't know what they are
> *really* called, but they are the ones that control which
> bitplane gets written to in EGA mode
> 640x350x16, 4 bitplanes) to me (please)?

There are several write modes and read modes for EGA/VGA, and the
exact workings of the registers depend on the mode. What you are
talking about (I assume) is read/write mode 0 which you would use
to pump bytes directly into a bit plane. I use the following
procedure for this:


(*************************** EGA/VGA bit planes ****************************)
}

CONST
  GDCIndexReg = $3CE;  { Index register of EGA/VGA Graphics Device Controller }
  GDCDataReg  = $3CF;  { Data  register of EGA/VGA Graphics Device Controller }
  SeqIndexReg = $3C4;  { Index register of EGA/VGA Sequencer }
  SeqDataReg  = $3C5;  { Data  register of EGA/VGA Sequencer }

PROCEDURE PrepareBitPlaneRead(Plane: Byte);
  BEGIN
    Port[GDCIndexReg] := 5;           { Number of Mode register }
    Port[GDCDataReg ] := 0;           { Value of register: 0: read mode 0 }
    Port[GDCIndexReg] := 4;           { Number of Read Map Select register }
    Port[GDCDataReg ] := Plane;       { Value of register: bit for plane to
read }
  END; { PrepareBitPlaneRead }


PROCEDURE ConcludeBitPlaneRead(Plane: Byte);
  BEGIN
    Port[GDCIndexReg] := 5;           { Number of Mode register }
    Port[GDCDataReg ] := $10;         { Value of register: 10: default for
modes 10h and 12h }
    Port[GDCIndexReg] := 4;           { Number of Read Map Select register }
    Port[GDCDataReg ] := 0;           { Value of register: plane to read }
  END; { ConcludeBitPlaneRead }


PROCEDURE PrepareBitPlaneWrite(Plane,PutMode: Byte);
  BEGIN
    Port[GDCIndexReg] := 5;           { Number of Mode register }
    Port[GDCDataReg ] := 0;           { Value of register: 0: write mode 0 }
    Port[GDCIndexReg] := 1;           { Number of Enable Set/Reset register }
    Port[GDCDataReg ] := 0;           { Value of register: 0 }
    Port[GDCIndexReg] := 3;           { Number of Data Rotate/Function Select
register }
   (* Bits 3 and 4 from the Rotate/Function Select register mean:
    *          Bit 4  Bit 3   Replacement function:
    *            0      0           Replace
    *            0      1           AND
    *            1      0           OR
    *            1      1           XOR    *)
    CASE PutMode OF
      AndPut : Port[GDCDataReg] :=  8;   { No rotation; AND with buffer }
      OrPut  : Port[GDCDataReg] := 16;   { No rotation; OR  with buffer }
      XORPut : Port[GDCDataReg] := 24    { No rotation; XOR with buffer }
    ELSE
      Port[GDCDataReg] :=  0;    { No rotation; replace; use this as default }
    END; { CASE }
    Port[GDCIndexReg] := 8;           { Number of BitMask register }
    Port[GDCDataReg ] := $FF;         { Value of register: $FF: use all bits }
    Port[SeqIndexReg] := 2;           { Number of Map Mask register }
    Port[SeqDataReg ] := 1 SHL Plane; { Value of register: plane number }
  END; { PrepareBitPlaneWrite }


PROCEDURE ConcludeBitPlaneWrite(Plane: Byte);
  BEGIN
    Port[GDCIndexReg] := 1;           { Number of Enable Set/Reset register }
    Port[GDCDataReg ] := 0;           { Value of register: 0 }
    Port[SeqIndexReg] := 2;           { Number of Map Mask register }
    Port[SeqDataReg ] := $0F;         { Value of register: Enable all planes }
    Port[GDCIndexReg] := 3;           { Number of Data Rotate/Function Select
register }
    Port[GDCDataReg ] := 0;           { Value of register: No rotation; replace
}
  END; { ConcludeBitPlaneWrite }

{
A good explanation can be found in:
  Wilton,R - Programmers' guide to PC and PS/2 video systems
  Microsoft Press

You should invest in some books on EGA/VGA programming if you have
more of these questions, otherwise you're being 'penny wise, pound
foolish'.

The book by Wilton is considered more or less a 'must have' together
with
  Ferraro, R.F. - Programmer's guide to the EGA and VGA cards
  Addison-Wesley

Ferraro gives you detailed register info. It also deals with Super
VGAs. Because I'll have to expand a program to use VESA super VGA
modes, I bought this together with:
  Rimmer, S - Super VGA graphics programming secrets
  WindCrest/McGraw Hill
}

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