DEMENTŮV VBE BUGLIST

     (Poznámka nad čarou: Tohle není angličtina. Ale kdyby to snad někdo
       za angličtinu považoval a upozornil mě na chyby, budu jen rád.)

------------------------------------------------------------------------------

                     Dement's VBE buglist  (version 1.5)

When you want to make your demo working in higher resolutions, you'll probably
cope with VBE  (Vesa Bios Extension). There is  an official VBE documentation,
it's cool.  The code should  work the same  way with all  cards, cool. But  it
doesn't, cool...ugh.  If you don't  want to require  particular VBE (hope  you
don't), you must adapt your  code to minor incompatibilities between different
VBEs. He, what incompatibilities?, bugs!

I have included also  many important things which are  not documented or could
be overlooked in VBE documentation and therefore cause troubles.

#DEFINE SCOV  Some Cards Or VBEs
#DEFINE BUG   It is a bug (acceptable bug which couldn't cause real trouble).
#DEFINE FATAL It is a fatal bug.
#DEFINE IMP   It is an important thing 2 know.

TYPE  * Description of a problem.
?     . How to detect it.
!     . How to solve it.
???   . Something I dont know, help.

                             4F00 - get VBE info

FATAL * SCOV write beyond the end of a given buffer.
!     . 512 bytes is enough for everybody.

IMP   * SCOV have duplicate modes (for example, modes 258, 369, 456 and twenty
        others are identical).
!     . Skip duplicate modes.

IMP   * SCOV have its  OEM modes beyond the end of  a modelist (std.modes, -1,
        OEM modes, -1).
!     . You can  look there safely  in real mode.  In protected mode  you must
        query segment limit to avoid GPF.
???   . It's very frequent,  but it't not documented in VBE  2.0. I don't know
        VBE 1.x, do you?

IMP   * SCOV  support  old  VGA  modes  with  numbers<80h,  they are listed in
        a modelist.
!     . Enjoy.

IMP   * "Stub" VBEs  have empty modelist  (starting with -1)  and support only
        4F00h function.
!     . Enhance your Detect_VBE function to check also modelist.

IMP   * SCOV have #7-like chars inside vesa_oem_string.
!     . Filter out chars under #32, #7 sux :).

FATAL * SCOV return bad total_memory.
!     . This  is luckily  very rare  bug. There  is no  way to  detect if card
        returns  less memory  than available  (note, setting  unavailable bank
        could  cause crash).  Luckily, it's  not a  fatal bug.  But let's have
        a closer look at SCOV returning more memory, which is fatal bug. Write
        0 to [0] and 1 to [total_memory*32K]. Now read these two bytes. If you
        have incorrect  total_memory, you will probably  read incorrect values
        - 1 at [0] or non1 at [total_memory*32K].

FATAL * SCOV say  "I'm VGA compatible" but  they are not. {They  kick out CRTC
        and some other  VGA registers after setting VESA  mode. SCOV's 3DAh in
        VESA modes return values different from VGA's 3DAh. Bit 0 (vertical or
        horizontal  retrace flag)  is clear,  bit 3  (vertical retrace)  shows
        vertical OR HORIZONTAL retrace.}
!     . You  can  say  that  you  don't  support  such  a  buggy  VBE  and  an
        incompatible  card. But  there is  another solution.  Don't use  CRTC.
        Enhance  your wait_for_vertical_retrace  routine to  ignore too  short
        retraces (which could be only horizontal).

IMP   * 4f00h  func returns  pointer to   a modelist.  Majority of  cards will
        return pointer to ROM, but SCOV put mode numbers into 4f00h func reply
        buffer. It means, you'll find modelist  in your RAM, usually at offset
        80h. If  you use the same  buffer for 4f00h func  return and for 4f01h
        func  return  (while  searching  in  modelist),  you will rewrite mode
        numbers by  zeros and you'll never  reach 0ffffh value (end  of a mode
        list).

FATAL * VBE 2.0 supports direct access  into VRAM, without bank switching. You
        can  obtain physical  address (in  CPU's address  region) where card's
        VRAM  is mapped.  It speeds  up  your  application (up  to 30%  faster
        transfers).  However, SCOV  (having VBE  2.0 and  saying YES, there IS
        linear  framebuffer available)  does not  work (no  transfer is  done,
        screen is blank).
?     . Check if your address points to read/write memory (modify one byte and
        read it). It's not 100% detection, but still much better than nothing.

                            4F01 - get mode info

FATAL * Another "VGA compatible" flag, the same lie as previous bug in 4F00.

BUG   * SCOV say "I support that mode"  but they don't.
!     . The  truth  will  appear  when  you  compare screensize with available
        memory or when you try to set that mode.

FATAL * SCOV in textmode return bad BytesPerLine.
?     . Compare BytesPerLine with 2*PixelsPerLine. Difference could mean bug.

IMP   * SCOV use unusual combinations of  two windows, one for reading, second
        for writing etc.
!     . Don't ignore  what VBE tell's  you in flags,  be happy that  you don't
        have to autodetect  it :). Work with two pointers,  first one for read
        window, second one for write window.

???   * Textmodes have BitsPerPixel=4. What does it mean?

FATAL * SCOV  return bad  window segment  and size.  Example: you set textmode
        132x25 and VBE returns segment A000, size 64KB. But real window is at
        B800, size 32KB.
?     . Check if your segment points to read/write memory (modify one byte and
        read it). It's not 100% detection, but still much better than nothing.

IMP   * SCOV do  not support Hi-Color modes  with 64K colors per  pixel. While
        32K and  64K color modes take  the same amount of  memory, SCOV do not
        support either 32K or 64K modes.
      ? It's not as easy as it might seem. See below.
      ! You should write your routines twice  (for each color mode) and detect
        which one is  supported. On many VBE's there are  both so then you can
        choose one (please 64K :-)).

BUG   * SCOV  do not  provide "consistent"  information about  Hi-Color modes.
        Mode information function  (4f01h) returns 16 bits per  pixel (byte at
        offset 19h),  BUT RGB scheme  (bytes 1fh..26h) says:  5 bits per  R, 5
        bits per G , 5 bits per B and 1 bit unused.
      ? Compare byte  at 19h and  sum bytes at  1fh, 21h and  23h. If there is
        a diference, card driver lies.
      ! Never count  on information at  offset 19h, you  should always examine
        color scheme. If you omit it, you'll get ugly green-gray pictures.

BUG   * SCOV  include both  32K and  64K  modes  in a  modelist, but  actually
        support  only  one  of  them.  For  example,  you  can find modes 110h
        (640*480*32K) and  mode 111h (640*480*64K). If  you call 4f01h, you'll
        get correct answer  (mode 110h will have byte 19h  == 15 and mode 111h
        will have byte  19 == 10h). BUT color scheme  will be 5:5:5:1 for BOTH
        the modes.
      ? The same way as previous.
      ! Do not  belive byte 19h, never  count on mode number  assignment. Test
        every number  in a mode  list, you should  always test a  color scheme
        (bytes 1fh..26h).

                               4F02 - set mode

IMP   * Numbers of OEM modes are not defined.
!     . Don't use  UniVBE mode numbers!  If you are  so lame you  can't search
        through  a modelist  for desired  resolution, I'll  send you code that
        does it.

                           4F06 - scanline length

IMP   * SCOV don't support scanline lengths below defaulth length.
!     . Dont even think about such scanline lengths in vesa modes.

FATAL * When you set  scanline length, some cards say "ok,  I set it" but they
        don't.  Simple  check  via  get  scanline  length  doesn't work, "get"
        returns bad value.
?     . Scan CRTC register  for scanline length BEFORE and  AFTER calling VBE.
        Changed? -> VBE  is ok. Not changed? -> Could  be bug, ask user (HINT:
        set new scanline length and write two messages, first one readable for
        default scanline length, second for new scanline length).
!     . It's a sad life with default scanline length. Nothing cool to say.

IMP   * SCOV don't support this function. It's the same thing as previous bug,
        but nice VBE tells us about it.

FATAL * When you set  new scanline length, SCOV sets  it physically, but their
        other  functions ignore  new value,  still working  with old  scanline
        length.  They are:  set display  start, set  cursor position.
?     . ---set display start---
        Set new scanline length. Set new display start, but scan CRTC register
        for display  start BEFORE and  AFTER calling VBE.  Changed as expected
        for good VBE ((dx+dy*NEW_scanline_length)/2^something)?  -> VBE is ok.
        Changed  as  expected  for  bad  VBE ((dx+dy*DEFAULT_scanline_length)/
        /2^something)? -> Bug detected. Else, ask user (HINT: when you set new
        scanline length and new display start, you can write something and ask
        user if it's to the left or to the right on screen).
        ---set cursor position (via old BIOS)---
        The same way with cursor position instead of display start.
!     . To     make     BIOS's     X+Y*DEFAULT_scanline_length     work     as
        X+Y*NEW_scanline_length, you must  recalculate coordinates before each
        call.

                            4F07 - display start

BUG   * SCOV ignore lower bits of X or  Y. It's not documented, so it's a bug.
        It often happens to X and Y in textmode, to X in graphics.
?     . Ask user (be creative :)).
!     . Sometimes it's possible to set lower bits with CRTC panning register.

FATAL * SCOV in textmode don't use correct units  for X and Y. Correct unit is
        pixel. I have met VBEs using char for  X or chars for both or char for
        Y and 1/2 of char for X, VBE maker's fantasy has no limits.
?     . Detect BugFactorX, BugFactorY in multiple steps. Write two things that
        only one will be visible after setting display start wisely.
!     . Use BugFactor  to modify X  and Y before  each "set disp.start"  call.
        Never use "get disp.start" when it's not necessary.

FATAL * When you  set display start,  some cards say  "ok, I set  it" but they
        don't. Simple check via get  display start doesn't work, "get" returns
        bad value.
???   . Has anybody  else experienced this bug?  It's a long time  and I'm not
        sure if it was VBE error or my error.

FATAL * SCOV crash when you set display address start out of range.

IMP   * Some VBEs 1.x wait for retrace  (AX=4F07, BX=0). VBEs 2.0 wait only if
        BX=80h.
???   . I don't know  VBE 1.x standard,  is it correct  to wait for  a retrace
        when BX=0?

BUG   * SCOV set  display start although  they should fail.  {Should fail when
        full page  of video memory isn't  available (position near the  end of
        vram and card don't wrap).}

                                  Wrapping

IMP   * SCOV don't wrap, SCOV wrap at the  end of a vram, SCOV wrap before the
        end of a vram.
?     . ---detecting wrapping before end of memory---
        Repeat test for wrapping for  each 2^something bound. Write two things
        that  only one  will be   visible after  setting display  start wisely
        (wrapping will hide or reveal one of them).
        ---detecting no_wrapping---
        One possible way is to write "prez 1" to end of video memory and "prez
        2, diz  haz higher priority" to  start of video memory.  Only first or
        both will be visible when you set display start wisely.

IMP   * SCOV wrap, but with some change in displaying. Top lines (from the end
        of vram) are ok, but bottom lines (from the beginning of vram) display
        pixels in some ugly order.

IMP   * SCOV wrap at the end of vram,  but don't wrap at some multiple of vram
        size.  Example:  card  with  1MB,  mode  1024x768/256. SetStart(0,900)
        wraps, SetStart(0,1024+900) doesn't wrap.

                                    Other

IMP   * Some cards  in some random vesa  modes split screen at  scanline 0 (it
        looks like if somebody locked display address start at 0) when you set
        line  compare register  exactly to  number of  scanlines. Other  cards
        unsplit screen.
!     . Never  set line  compare register   to number  of scanlines,  set only
        values from 0 to scanlines-1. Top window has line compare+1 scanlines.

IMP   * Reading from vram could be much slower than writing to.

IMP   * Some VBE functions don't work in protected mode? :)
!     . It's not a bug, use DPMI SimulateRealModeInt to access that functions.


Thanks to Ladislav Wagner and John Patera for their bugs and advices.

Comments, questions, cool new bugs? Write to
                                                 Dement / Downtown
                                                 dement@bbs.infima.cz
                                                 shrb5163@barbora.mff.cuni.cz


            výheň