Video Memory Layouts

  BIOS video output services such as INT 10H 0aH (write character) are
  typically far too slow for most purposes.  Nearly all programs write
  directly to video memory for performance reasons.

  This topic describes the location and layout of video memory for the
  various video systems.

█▌Text Modes▐█
  Video modes 00H-03H and 07H (see Video Modes) use the following video-
  memory layout:

        0   1 ║ 2   3 ║ 4   5 ║ ... ║158 159
      ┌───┼───╫───┼───╫───┼───╫─────╫───┼───╖
     0│chr│atr║chr│atr║chr│atr║ ... ║chr│atr║ line 0, video page 0
      ├───┼───╫───┼───╫───┼───╫─────╫───┼───╢
   160│chr│atr║chr│atr║chr│atr║ ... ║chr│atr║ line 1
      ├───┼───╫───┼───╫───┼───╫─────╫───┼───╢
   320│chr│atr║chr│atr║chr│atr║ ... ║chr│atr║ line 2
      ├───┼───╫───┼───╫───┼───╫─────╫───┼───╢
   480│chr│atr║chr│atr║chr│atr║ ... ║chr│atr║
      ├───┼───╫───┼───╫───┼───╫─────╫───┼───╢
      \                                     \
      ├───┼───╫───┼───╫───┼───╫─────╫───┼───╢
  3840│chr│atr║chr│atr║chr│atr║ ... ║chr│atr║ line 24
      └───┴───╨───┴───╨───┴───╨─────╨───┴───╜
       ...small gap...
      ┌───┼───╫───┼───╫───┼───╫─────╫───┼───╖
  4096│chr│atr║chr│atr║chr│atr║ ... ║chr│atr║ line 0, video page 1
       ...etc...

  All even-numbered addresses contain characters (see Character Set) and
  all odd-numbered addresses contain video attributes.

  The width of a standard 80-column line is 160 bytes and there are 25 lines
  (0-24) in most cases.  But these can be changed by various video services
  or TSRs or device drivers.  Programs should check the width and height of
  the screen via INT 10H 0fH or INT 10H 1130H or by examining variables in
  the BIOS Data Area.

  On EGAs and VGAs, it is possible to remap the video attributes so that
  any attribute byte can represent any desired color (see INT 10H 10H).
  You can also redefine the characters; for instance, to display italics or
  foreign-language text.  See INT 10H 11H and Video Font Definition.

  Accessing Text Mode Video Memory
    ■ Text mode video memory begins at b800:0 on CGA, EGA and VGA and at
      b000:0 on MDA.

      Use INT 12H to see if MDA is active and set up a segment register
      accordingly.

    ■ Given an X,Y coordinate (clm,row), calculate a memory location as:

        vidAddr = (row * 160 )+ (clm * 2)

      Note: For best flexibility, don't hard-code "160".  Instead, fetch
      the word at 0040:004a in the BIOS Data Area and multiply it by 2.

    ■ Store a character at that position and an attribute one address
      higher.  Most applications use 16-bit commands such as...

         mov  word ptr ES:[DI],AX
      or
         stosw

      ...to write both a character and attribute to video memory in one
      operation.

  Special care must be taken when using direct-memory access on CGA
  adapters.  See Video Snow for a discussion.

  Also, all video systems except MDA provide multiple "pages" of video
  memory.  It is possible to write to a secondary page then swap it into
  view via INT 10H 05H.  But this is seen rarely: CPUs are now fast enough
  to update the screen in place without flicker.  If you are writing to a
  video page other than 0, check 0040:004e for the offset of the start of
  the video page.

█▌Graphics Modes▐█
  Graphics-mode video memory layouts vary considerably, depending on the
  mode.  The following summarizes each standard video graphics mode:

  CGA Low-res 320x200, 4-color (video modes 04H and 05H)
 Segment: b800
  Layout: Interleaved scan lines, packed-pixel.  Even-numbered scan lines
          begin at b800:0, and odd-numbered lines begin at b800:2000.

          Each scan line is 80-bytes long and there are 200 scan lines
          (regen size=8000 bytes * 2 regions).  Each byte contains 4 pixels
          (16,000 total pixels):
          ╓7┬6┬5┬4┬3┬2┬1┬0╖
          ║   │   │   │   ║
          ╙─┴─┴─┴─┴─┴─┴─┴─╜  bits mask
           ╚╦╝ ╚╦╝ ╚╦╝ ╚═╩═► 0-1:  03H  fourth pixel in byte
            ║   ║   ╚══════► 2-3:  0cH  third pixel in byte
            ║   ╚══════════► 4-5:  30H  second pixel in byte
            ╚══════════════► 6-7:  c0H  first pixel in byte
                                        00=black;       01=green/cyan
                                        10=red/magenta; 11=brown/white

          Each 2-bit field selects one of four colors, depending on the
          setting of the CGA palette.  Use INT 10H 0bH.
 ──────────────────────────────────────────────────────────────────────────
  CGA Hi-res 640x200, 2-color (video mode 06H)
 Segment: b000
  Layout: Interleaved scan lines, packed-pixel.  Even-numbered scan lines
          begin at b800:0, and odd-numbered lines begin at b800:2000.

          Each scan line is 80-bytes long and there are 200 scan lines
          (regen size=8000 bytes * 2 regions).  Each byte contains 8 pixels
          (32,000 total pixels):
          ╓7┬6┬5┬4┬3┬2┬1┬0╖
          ║ │ │ │ │ │ │ │ ║
          ╙╥┴╥┴╥┴╥┴╥┴╥┴╥┴╥╜  bits mask
           ║ ║ ║ ║ ║ ║ ║ ╚══► 0:  01H  eighth pixel in byte
           ║ ║ ║ ║ ║ ║ ╚════► 1:  02H  seventh pixel in byte
           ║ ║ ║ ║ ║ ╚══════► 2:  04H  sixth pixel in byte
           ║ ║ ║ ║ ╚════════► 3:  08H  fifth pixel in byte
           ║ ║ ║ ╚══════════► 4:  10H  fourth pixel in byte
           ║ ║ ╚════════════► 5:  20H  third pixel in byte
           ║ ╚══════════════► 6:  40H  second pixel in byte
           ╚════════════════► 7:  80H  first pixel in byte
                                       0=black; 1=white

          Each 1-bit field selects black (0) or white (1).
 ──────────────────────────────────────────────────────────────────────────
  EGA 320x200, 16-color (video mode 0dH)
 Segment: a000
  Layout: 4-plane planar.  Each pixel color is determined by the combined
          value of bits in the four color planes.  Each color plane begins
          at a000:0.  To select a plane, use:

            OUT 3ceH, 0005H         ;set up for plane masking
            OUT 3c4H, n             ;n is: 0102H=plane 0; 0202H=plane 1
                                    ;      0402H=plane 2; 0802H=plane 3
            ...(write video data)...
            OUT 3c4H, 0f02H         ;restore normal plane mask

          Each scan line is 40 bytes long and there are 200 scan lines
          (regen size=16,000 bytes * 4 planes).  Each byte contains
          8 pixels (64,000 total pixels):
          ╓7┬6┬5┬4┬3┬2┬1┬0╖
          ║ │ │ │ │ │ │ │ ║
          ╙╥┴╥┴╥┴╥┴╥┴╥┴╥┴╥╜  bits mask
           ║ ║ ║ ║ ║ ║ ║ ╚══► 0:  01H  eighth pixel in byte
           ║ ║ ║ ║ ║ ║ ╚════► 1:  02H  seventh pixel in byte
           ║ ║ ║ ║ ║ ╚══════► 2:  04H  sixth pixel in byte
           ║ ║ ║ ║ ╚════════► 3:  08H  fifth pixel in byte
           ║ ║ ║ ╚══════════► 4:  10H  fourth pixel in byte
           ║ ║ ╚════════════► 5:  20H  third pixel in byte
           ║ ╚══════════════► 6:  40H  second pixel in byte
           ╚════════════════► 7:  80H  first pixel in byte
                                       0=color OFF; 1=color ON

          The pixel color depends on the 4-bit value (0-15) obtained by
          combining the same bit position in each plane.  Default settings
          are:   0H black     8H gray
                 1H blue      9H bright blue
                 2H green     aH bright green
                 3H cyan      bH bright cyan
                 4H red       cH bright red
                 5H magenta   dH bright magenta
                 6H brown     eH yellow
                 7H white     fH bright white
          For instance, to make a pixel blue, the combined planes must
          equal 01H; that is the bit in plane 0 is set and the bits in
          planes 1,2, and 3 are clear.

          The actual colors depend on the palette (see INT 10H 1000H).
 ──────────────────────────────────────────────────────────────────────────
  EGA 640x200, 16-color (video mode 0eH)
 Segment: a000
  Layout: 4-plane planar.  Each pixel color is determined by the combined
          value of bits in the four color planes.  Each color plane begins
          at a000:0.

          Each scan line is 80 bytes long and there are 200 scan lines
          (regen size=16,000 bytes * 4 planes).  Each byte contains
          8 pixels (128,000 total pixels).

          The layout and access is the same as mode 0dH.
───────────────────────────────────────────────────────────────────────────
  EGA 640x350, 4-color (video mode 0fH)
 Segment: a000
  Layout: 2-plane planar.  Video layout is the same as modes 0dH and 0eH,
          except that only planes 0 and 2 are used.  The effect is to have
          only two bits per pixel and the four colors are determined by
          palette registers 0, 1, 4, and 5.

          Each scan line is 80 bytes long and there are 350 scan lines
          (regen size=28,000 bytes * 2 planes).  Each byte contains
          8 pixels (224,000 total pixels).

          On really-old EGAs with only 64K, the even-numbered bit positions
          in video memory are displayed for planes 0 and 2 and odd-numbered
          pixels are in planes 1 and 3.  This variation is seen rarely.
 ──────────────────────────────────────────────────────────────────────────
  EGA 640x350, 16-color (video mode 10H)
 Segment: a000
  Layout: 4-plane planar.  Video layout is the same as modes 0dH and 0eH,
          where the pixel is determined by the combined value in all four
          color planes.

          Each scan line is 80 bytes long and there are 350 scan lines
          (regen size=28,000 bytes * 4 planes).  Each byte contains
          8 pixels (224,000 total pixels).
 ──────────────────────────────────────────────────────────────────────────
  VGA 640x480, 2-color (video mode 11H)
 Segment: a000
  Layout: 4-plane planar.  In this mode, there is a one-to-one
          correspondence to bits in color plane 0 and the displayed data.

          Each scan line is 80 bytes long and there are 480 scan lines
          (regen size=38,400 bytes).  Each byte contains 8 pixels (307,200
          total pixels).
 ──────────────────────────────────────────────────────────────────────────
  VGA 640x480, 16-color (video mode 12H)
 Segment: a000
  Layout: 4-plane planar.  Video layout is the same as modes 0dH and 0eH,
          where the pixel is determined by the combined value in all four
          color planes.

          Each scan line is 80 bytes long and there are 480 scan lines
          (regen size=38,400 bytes * 4 planes). Each byte contains 8 pixels
          (307,200 total pixels).
 ──────────────────────────────────────────────────────────────────────────
  VGA 320x200, 256-color (video mode 13H)
 Segment: a000
  Layout: Linear, packed-pixel.  This mode uses one byte (8 bits) per
          pixel.  The colors displayed depend on the palette settings.

          Each scan line is 320 bytes long and there are 200 scan lines
          (regen size=64,000 bytes).  Each byte contains 1 pixel (64,000
          total pixels).

See Also: Screen Attributes
          Video Modes
          Video Font Definition
          INT 10H (Video Services)
          SVGA Video Modes
                                    -♦-