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ň