Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

DOS VGA Screensaver Issue: Keeping Running Program Working on Text Screen?

101 views
Skip to first unread message

Harry Potter

unread,
Sep 30, 2016, 10:26:43 AM9/30/16
to
Hi! I just found some docs. on saving the screen state from BIOS. Now, I want to create a DOS screensaver that will allow a text-based application to keep writing text while the screen saver is active. The application should be able to use BIOS and DOS to access the text screen. Now, how do I do *that*?

JJ

unread,
Oct 1, 2016, 5:28:13 AM10/1/16
to
How do you know if it's even possible?

Harry Potter

unread,
Oct 1, 2016, 7:46:48 AM10/1/16
to
I think I know of a way:

* Use the BIOS to save the current state;
* Save the BIOS video data to a temporary buffer and the palettes;
* Switch to VGA256 and restore the video data;
* Write to the screen directly *only*;
* When done, restore the video data.

What do you think? :)

Alexei A. Frounze

unread,
Oct 1, 2016, 9:31:55 AM10/1/16
to
On Friday, September 30, 2016 at 7:26:43 AM UTC-7, Harry Potter wrote:
> Hi! I just found some docs. on saving the screen state from BIOS. Now, I want to create a DOS screensaver that will allow a text-based application to keep writing text while the screen saver is active. The application should be able to use BIOS and DOS to access the text screen. Now, how do I do *that*?

The same way as Windows does it. Use the virtual 8086 mode
and page translation, intercept and handle I/O and memory
accesses and interrupts and simulate the graphics card's
text mode. It will be a lot of work and I don't think
the nifty screen saver is worth it, unless you're into
implementing something much bigger, e.g. an OS that among
other things can run DOS software.

Alex

Harry Potter

unread,
Oct 1, 2016, 12:13:19 PM10/1/16
to
On Saturday, October 1, 2016 at 9:31:55 AM UTC-4, Alexei A. Frounze wrote:
> The same way as Windows does it. Use the virtual 8086 mode
> and page translation, intercept and handle I/O and memory
> accesses and interrupts and simulate the graphics card's
> text mode. It will be a lot of work and I don't think
> the nifty screen saver is worth it, unless you're into
> implementing something much bigger, e.g. an OS that among
> other things can run DOS software.
>
That explains why nobody *else* did it. :( I think I can get it to work under some restrictions (i.e. blank only in text/CGA graphics modes), though.

Rod Pemberton

unread,
Oct 1, 2016, 7:33:20 PM10/1/16
to
Shouldn't the BIOS or app continue writing to the text screen even if
someone switched video into a graphics mode?

I've not attempted this, but my guess is you could switch into a
graphics mode. The app will continue to write directly to the text
screen or call BIOS that writes to the text screen. As long as the
graphics mode you chose uses a different block memory, there would be
no corruption of the text screen. So, you probably only need to be
able to switch to a graphics mode and back. E.g., Linux starts up in
text mode, writes a bunch of text messages, switches to graphics mode
for normal use, returns to text mode during shutdown, and all the
original text messages are present on the text screen. I doubt that
they rewrote these messages.


Rod Pemberton

Harry Potter

unread,
Oct 2, 2016, 4:41:36 PM10/2/16
to
On Saturday, October 1, 2016 at 7:33:20 PM UTC-4, Rod Pemberton wrote:
> Shouldn't the BIOS or app continue writing to the text screen even if
> someone switched video into a graphics mode?
>
Yes, it should, *if* I restore the BIOS screen data mode after switching modes.

> I've not attempted this, but my guess is you could switch into a
> graphics mode. The app will continue to write directly to the text
> screen or call BIOS that writes to the text screen. As long as the
> graphics mode you chose uses a different block memory, there would be
> no corruption of the text screen. So, you probably only need to be
> able to switch to a graphics mode and back. E.g., Linux starts up in
> text mode, writes a bunch of text messages, switches to graphics mode
> for normal use, returns to text mode during shutdown, and all the
> original text messages are present on the text screen. I doubt that
> they rewrote these messages.
>
Well, I'm planning to use VGA256 mode. :)

Jim Leonard

unread,
Oct 10, 2016, 4:38:02 PM10/10/16
to
On Friday, September 30, 2016 at 9:26:43 AM UTC-5, Harry Potter wrote:
> Hi! I just found some docs. on saving the screen state from BIOS. Now, I want to create a DOS screensaver that will allow a text-based application to keep writing text while the screen saver is active. The application should be able to use BIOS and DOS to access the text screen. Now, how do I do *that*?

If your screensaver uses no BIOS calls that change state (set graphics mode, plot pixels, etc.), then this is possible if you:

- Manually set the video mode using register writes only (no BIOS calls)
- Write to video memory manually (no BIOS calls)
- Use a video mode that does not collide with text mode (ie. text mode and CGA graphics modes both use b800:0000, so use MCGA 320x200x256 which is at a000:0000)
- Use a video mode that does not change the chain/bitplane mode of text mode (ie. don't use mode-x)
- Switch back to text mode using register writes only (if on a VGA system, you can read registers before starting which will make this easier for you) and without clearing the screen

If you don't change anything using the BIOS, then the source BIOS/DOS application will be able to continue plotting characters using BIOS/DOS calls which will put characters into b800:xxxx. Your screensaver should probably hook int 08 so that it can perform an update every timer tick which would be at about 18.2 Hz.

This is a great deal of effort for something that will not work on all systems and situations. Maybe there is an easier project you can work on.

Alexei A. Frounze

unread,
Oct 11, 2016, 2:58:31 AM10/11/16
to
I'm very skeptical about the BIOS and the video chip
working in two different modes simultaneously.

I remember writing a tool to "fix" worn-out displays.
The tool simply reprogrammed the default VGA palette
to brighter colors (using ports 3C8 and 3C9). That
worked in text modes.
IOW, at least the EGA/VGA palette/DAC state may be
shared between text and video modes. But I think
there's more than that.

AFAIK, for two modes people used to use two video
cards (color + monochrome) with two displays. But
that's a totally different thing.

Alex

Mateusz Viste

unread,
Nov 6, 2016, 11:27:23 AM11/6/16
to
On Sat, 01 Oct 2016 19:33:45 -0400, Rod Pemberton wrote:
> I've not attempted this, but my guess is you could switch into a
> graphics mode. The app will continue to write directly to the text
> screen or call BIOS that writes to the text screen. As long as the
> graphics mode you chose uses a different block memory, there would be no
> corruption of the text screen.

I really don't think this has any chance to work out. The fact that the
memory blocks appear to be at different locations (for ex. B800 vs A000)
doesn't necessarily mean they point to actually different VRAM areas on
the graphic card. It's only memory mappings after all. For instance, the
VGA comes with 256K of memory, all of which is available in graphic
modes, hence there's no room for any "parallel" text page storage at the
same time (and that would be quite a waste of VRAM memory otherwise).

Mateusz

Rod Pemberton

unread,
Nov 6, 2016, 2:12:47 PM11/6/16
to
On 06 Nov 2016 16:27:22 GMT
Mateusz Viste <mateus...@localhost.localhost> wrote:

> On Sat, 01 Oct 2016 19:33:45 -0400, Rod Pemberton wrote:

> > I've not attempted this, but my guess is you could switch into a
> > graphics mode. The app will continue to write directly to the text
> > screen or call BIOS that writes to the text screen. As long as the
> > graphics mode you chose uses a different block memory, there would
> > be no corruption of the text screen.
>
> I really don't think this has any chance to work out. The fact that
> the memory blocks appear to be at different locations (for ex. B800
> vs A000) doesn't necessarily mean they point to actually different
> VRAM areas on the graphic card. It's only memory mappings after all.

That's an interesting point. I agree that is plausible.

Before he starts coding this, this should be relatively easy for him to
determine if it works for his machine, yes?

Set the graphics video mode. Display a nice graphics image. Write
something to the text mode memory region, both directly and using a
BIOS call. Look for any corruption in the graphics image. Or, save
the image and compare it to the original with a binary file compare
utility.

If it works for him, he should be able to reasonably expect it to
work for most other AT clones. Of course, he might want to try out a
dozen or so first. He could also test the code with various PC
emulators to help confirm that it's standard behavior, e.g., Bochs,
QEMU, Virtual PC, DOSBox, MESS, etc.


Rod Pemberton

Mateusz Viste

unread,
Nov 7, 2016, 1:55:49 AM11/7/16
to
On Sun, 06 Nov 2016 14:13:15 -0500, Rod Pemberton wrote:
> Set the graphics video mode. Display a nice graphics image. Write
> something to the text mode memory region, both directly and using a BIOS
> call. Look for any corruption in the graphics image. Or, save the
> image and compare it to the original with a binary file compare utility.
>
> If it works for him, he should be able to reasonably expect it to work
> for most other AT clones.

I think that's highly dependent on the type of VGA card (and VGA BIOS)
that is installed. I'd expect the test to fail in most VGA-compatible
boards anyway (fail, meaning that no corruption would occur), simply
because the VGA should not intercept bus write pulses at B000 / B800
areas when in graphic mode, hence these would be simply ignored.

Of course this is all cheap/lazy talk on my part :) The OP should
definitely test it and then the ultimate truth will reveal itself.

Mateusz

R.Wieser

unread,
Nov 7, 2016, 3:04:44 AM11/7/16
to
Mateusz Viste,

> I'd expect the test to fail in most VGA-compatible boards
> anyway (fail, meaning that no corruption would occur),
> simply because the VGA should not intercept bus write pulses
> at B000 / B800 areas when in graphic mode, hence these
> would be simply ignored.

That problem is easily solved: I seem to remember that you can, using BIOS
commands, switch video modi without clearing the video-memory itself. So,
clear both a graphics and a text mode, write to one of them, switch to the
other *without* clearing the video memory and see if you get a "dirty"
display. If you do you can assume both video modi use the same VRam.

> I think that's highly dependent on the type of VGA card
> (and VGA BIOS) that is installed.

Agreed.

Regards,
Rudy Wieser



-- Origional message:
Mateusz Viste <mateus...@localhost.localhost> schreef in berichtnieuws
58202574$0$7967$426a...@news.free.fr...

Mateusz Viste

unread,
Nov 7, 2016, 3:45:56 AM11/7/16
to
On Mon, 07 Nov 2016 09:06:34 +0100, R.Wieser wrote:
> That problem is easily solved: I seem to remember that you can, using
> BIOS commands, switch video modi without clearing the video-memory
> itself. So, clear both a graphics and a text mode, write to one of
> them, switch to the other *without* clearing the video memory and see if
> you get a "dirty" display. If you do you can assume both video modi use
> the same VRam.

Hi Rudy, this is a nice idea. I didn't know it was possible to instruct
the BIOS to *not* clear VRAM upon a graphic mode change. After a look
into RBIL I see that's indeed possible: "IBM standard modes do not clear
the screen if the high bit of AL is set (EGA or higher only)".

Here I paste a simple test program I wrote for the purpose of finding out
the answer to this thread. It switches into VGA 320x200x8 mode, fills the
screen with light green (ie. the 'a' value in default VGA palette), then
tries to corrupt the screen by writing to text VRAM at B800:0000, reads
back what it wrote, then switches back to text mode *without* clearing
the VRAM, and outputs a short extract of the 'garbage' it tried to
corrupt the screen with earlier.

I tested it on both real hardware (on an early PVGA chip from Paradise),
as well as on DOSEMU and DOSBox. Result is the same in all three cases.

Observations:
1. screen doesn't get corrupted when writing to B800:0000 in graphic mode.
2. screen is not corrupted, but writes to B800:0000 aren't lost either.
3. Once back in text mode, the screen is all filled with 'a' characters.

Conclusion: the VRAM is shared between graphic and text modes, and writes
to B800:0000 while in graphic mode are ignored by the VGA chip,
(presumably) landing in a region of the system RAM that is usually (text
mode) intercepted by VGA.

/* a short program to test VGA's VRAM behavior / Mateusz Viste
* reference: USENET Message-ID: <581f59ea$0$7964$426a...@news.free.fr>
* compile with: wcl vramtest.c -0 -mt -od -wx
* the purpose of this test is to prove whether or not the VGA VRAM is
* shared between video and text modes, and whether or not any writes to
* the VGA text VRAM during graphic mode are lost. */
#include <stdio.h>
#include <dos.h>

int main(void) {
int x, y;
unsigned char buf[16];
union REGS r;
/* pointers to the VGA's VRAM start for text and graphic modes */
static unsigned char far *vgag = (unsigned char far*)0xA0000000l;
static unsigned char far *vgat = (unsigned char far*)0xB8000000l;
/* set VGA BIOS mode 13h */
r.x.ax = 0x0013;
int86(0x10, &r, &r);
/* paint it all in light green */
for (y = 0; y < 200; y++) {
for (x = 0; x < 320; x++) vgag[320 * y + x] = 'a';
}
/* wait 2s and try corrupting the screen */
sleep(2);
for (x = 0; x < 8000; x++) vgat[x] = x;
/* read back what I wrote to text screen */
for (x = 0; x < 16; x++) buf[x] = vgat[x];
/* wait 2s, restore text mode, WITHOUT clearing VRAM */
sleep(2);
r.h.ah = 0;
r.h.al = 128 | 3; /* high bit set means 'do not clear vram' */
int86(0x10, &r, &r);
/* print the 'garbage' I had written to text VRAM while in 320x200 */
for (x = 0; x < 16; x++) printf("%d ", buf[x]);
return(0);
}

This means, however, that for the purpose of the OP, what he wanted to do
might still be possible, since the content of what is written to the text
area buffer is not lost while in graphic mode (and doesn't corrupt the
screen either), hence the OP might run his screen saver application, and
let the text mode program continue writing to text mode VRAM. Then,
before switching the screen saver off (ie. before switching into text
mode again), he'd need to dump the content of the RAM at B800:0000, and
only then switch back to text mode, and then restore the content of the
area at B800:0000 (because this area got 'rewired' back to VGA in the
meantime).

I hope I got it all right, and didn't miss anything during this
experiment. Feel free to point out any mistake in either code or
deduction I could have made.

cheers,
Mateusz

R.Wieser

unread,
Nov 7, 2016, 5:06:32 AM11/7/16
to
Mateusz,

> After a look into RBIL

That is where I took my clue from too (again, thanks ralf :-) )

> Conclusion: the VRAM is shared between graphic and text
> modes, and writes to B800:0000 while in graphic mode are
> ignored by the VGA chip,

From your observations I would conclude the opposite: The areas are *not*
shared, as the data thats written to B800:0000 can, after switching back to
text mode, be viewed as provided (though a bit more testing, like, for
example, writing a simple text would be advisable)

Although not of value in regard to the OPs problem, the results of a reverse
test would be interresting too (select a textmode and write to a (320x200)
graphics mode address. Would you see the drawn graphics when you switch to
graphics mode without clearing the screen).

> (presumably) landing in a region of the system RAM that is usually (text
> mode) intercepted by VGA.

As graphics and text writes go to different system adresses, why would VGA
need to intercept anything ? It would be a simple case of using a
different system-to-vram-address translation.

> This means, however, that for the purpose of the OP, what he
> wanted to do might still be possible,

To me it sounds that your results indicate that what the OP wants to do is
*very* possible: Switch to screen-saver VGA mode erasing the vram, switch
back to textmode without erasing the vram. easy-peasy. (for the in-between
time he still needs to intercept OS/BIOS writes to that textscreen and
create his own routines for it though).

Regards,
Rudy Wieser


-- Origional message:
Mateusz Viste <mateus...@localhost.localhost> schreef in berichtnieuws
58203f43$0$5421$426a...@news.free.fr...

Mateusz Viste

unread,
Nov 7, 2016, 5:31:45 AM11/7/16
to
Hi Rudy,

My explanation was perhaps too obscure, and the test not as clear as I
thought. Let me rephrase.

> From your observations I would conclude the opposite: The areas are
> *not* shared, as the data thats written to B800:0000 can, after
> switching back to text mode, be viewed as provided (though a bit more
> testing, like, for example, writing a simple text would be advisable)

The above statement is not true. The data that's written to B800:000 is
NOT viewed as provided after switching back to text mode. Instead, the
"graphic" data is seen (in my test - all the screen is filled with 'a',
which is the value of light green pixels I filled the video mode with).

I'm sorry if my test seemed to be confusing - in fact, I included two
different tests there:
1. is the VRAM shared? (yes, it is, because after switching into text
mode we still see the pixel data)
2. are writes to B800:0000 during video mode landing in some black hole?
(no, they are not - even though they do NOT land into VRAM, they
apparently still land somewhere, I can only assume they land into system
RAM, because the VGA is not intercepting the write pulses to B800:0000
during this time, so the bits continue their journey and land in system
RAM - I don't see where they would be stored otherwise).

> To me it sounds that your results indicate that what the OP wants to do
> is *very* possible: Switch to screen-saver VGA mode erasing the vram,
> switch back to textmode without erasing the vram. easy-peasy. (for the
> in-between time he still needs to intercept OS/BIOS writes to that
> textscreen and create his own routines for it though).

Agreed - what the OP wants seems very doable, although it's not as easy
as "switching to text mode without clearing VRAM", since the VRAM is
trashed by video writes, as explained above. The content of what the
application "behind" the screen saver wrote to the text screen is not
lost, though, due to this data being stored elsewhere (my assumption:
system RAM). So the trick would be to copy system's RAM at B800:0000 into
a buffer before switching back to text mode, and then restoring the
buffer to B800:0000 (because, again, B800:0000 in text mode points to
VRAM, while B800:0000 in graphic mode points to system RAM).

I hope my test, and the results I gathered, are clearer now.

best regards,
Mateusz

R.Wieser

unread,
Nov 7, 2016, 5:58:22 AM11/7/16
to
Mateusz,

> My explanation was perhaps too obscure, and the test not as
> clear as I thought. Let me rephrase.

My apoligies, I seem to have misread. I took your writes of 'a' to B800 as
being to the textscreen, and I also took it you saw those same back
(re-reading your message I do not quite know how I did that ... Sorry.)

> Instead, the "graphic" data is seen (in my test - all the screen
> is filled with 'a', which is the value of light green pixels I filled
> the video mode with).

Ah yes, that makes more sense (reads: lies in the line of my expectations
:-) )

So yes, your experiment seems to confirm that the text and graphics mode
vram is shared.

However, I (still) do not agree with your conclusion that a write to
text-mode memory while being in graphics mode *must* land somewhere. Its
rather possible that VGA, while being in graphics mode, doesn't "listen" to
that address range (its not mapped to anywhere) and the bytes are simply
ignored (wrinting to non-present memory tends to does that :-) )

Though, *if* the writes go somewhere, its most likely that they go to the
system-RAM that occupies the same memory range as the textmode screen. If
its there its possible that it can be read back using himem.sys (which
allows you do define several "upper memory" blocks for extra usage)

Regards,
Rudy Wieser


-- Origional message:
Mateusz Viste <mateus...@localhost.localhost> schreef in berichtnieuws
58205810$0$7097$426a...@news.free.fr...

Mateusz Viste

unread,
Nov 7, 2016, 6:24:41 AM11/7/16
to
On Mon, 07 Nov 2016 12:00:12 +0100, R.Wieser wrote:
> However, I (still) do not agree with your conclusion that a write to
> text-mode memory while being in graphics mode *must* land somewhere.
> Its rather possible that VGA, while being in graphics mode, doesn't
> "listen" to that address range (its not mapped to anywhere) and the
> bytes are simply ignored (wrinting to non-present memory tends to does
> that :-) )

Well, I do not assert that it *must* land somewhere in all situations and
in all universes. I only state that I *observed* it to land somewhere,
consistently on the three platforms I tested (DOSBox, DOSEMU and my
oldish 386SX with a PVGA video chip).

The test I posted earlier writes deterministic values (called "garbage"
in my test) to B800:0000 while in graphic mode. This data doesn't show up
on the screen, neither immediately nor after returning to text mode.
However, the exact same data can be reliably read back from B800:0000
while in graphic mode, so *in the scope of my test* it must land
somewhere other than VRAM.

R.Wieser

unread,
Nov 7, 2016, 9:07:35 AM11/7/16
to
Mateusz,

> However, the exact same data can be reliably read back
> from B800:0000 while in graphic mode, so *in the scope
> of my test* it must land somewhere other than VRAM.

My apologies again. Yes, in that case (you can read the written contents
back) you're right ofcourse.

Though its rather unexpected: why should a single-process DOS machine have
such a text-mode screen access while in graphics mode, only to discards it
when it switches back to that textmode ?

Oh well, I guess that I will never know all of DOS-es secrets. :-)

Regards,
Rudy Wieser


-- Origional message:
Mateusz Viste <mateus...@localhost.localhost> schreef in berichtnieuws
58206478$0$4298$426a...@news.free.fr...

Ross Ridge

unread,
Nov 8, 2016, 12:23:43 AM11/8/16
to
Mateusz Viste <mateus...@localhost.localhost> wrote:
>Well, I do not assert that it *must* land somewhere in all situations and
>in all universes. I only state that I *observed* it to land somewhere,
>consistently on the three platforms I tested (DOSBox, DOSEMU and my
>oldish 386SX with a PVGA video chip).
>
>The test I posted earlier writes deterministic values (called "garbage"
>in my test) to B800:0000 while in graphic mode. This data doesn't show up
>on the screen, neither immediately nor after returning to text mode.
>However, the exact same data can be reliably read back from B800:0000
>while in graphic mode, so *in the scope of my test* it must land
>somewhere other than VRAM.

It would've been nice if you explained exactly what you meant by
your garbage test when you first mentioned it. My thinking was along
R.Wiesers, it was probably going nowhere since nothing you said showed
otherwise up until now. In anycase, I don't think this is behaviour
you can depend on. Who knows what the emulators you're using are doing,
but on real hardware there's four possible places the reads and writes
to the phyiscal adress B8000h can be ending up, nowhere, system RAM,
video RAM, or cache. Depsite your tests, nowhere seems to be the most
likely on real hardare. Your 386SX/PVGA case seems to be an exception,
and it appears mostly likely to me that it's actually going to video RAM.
I assume your system doesn't have any cache, and going system RAM because
of the video mode selected doesn't make sense to me.

Internally VGA graphics cards have only a 16-bit wide address bus, giving
internal addresses in the range of 0000h to FFFFh. However the data bus
is 32-bits wide, each address refers to a non-overlapping 32-bit value
in video memory. So a VGA card with 256 kilo-bytes of video memory is
actually internally orgianized as 64 kilo-dwords of RAM. Another way
to look at it is that the 256kb of video memory is divided into four
64kb planes, each plane corresponding to a different 8-bit byte of every
32-bit memory location.

How CPU memory accesses to the video memory regions (A0000h-BFFFFh) map
into interal VGA addresses depends on the video mode. The 16-colour
graphics modes offer the most direct mapping to video memory, and are
the only documented means by which the entire 256kb of VGA memory
can be accessed. In these modes the physical CPU addresses in the
range A0000h-AFFFFh directly map to VGA internal address. For example
CPU address A0000h is VGA adress 0000h, and CPU A1234h is VGA 1234h.
Each CPU byte access is mapped to one or more more bytes (planes) of the
32-bit VGA dword at that address. Which plane(s) depends on the setting
of various VGA control registers. For example to read every byte in
the 256kb video memory a program would need to read every byte in the
64kb A0000h region four times, changing the VGA registers as necessary
on to select which plane is being read.

In text modes, either the B0000h-B7FFFh (MDA compatible) or the
B8000-BFFFFh (CGA compatible) regions are mapped to VGA memory.
However the mapping isn't quite as simple as the 16-bit graphics modes.
Instead the video card uses an "even/odd" mapping. In this mapping,
even CPU addresses access plane 0 while odd addresses acces plane 1.
This puts the character values in plane 0 and the attribute values
plane 1. (Plane 2 is used for storing fonts, while plane 3 is unused.)
The least significant bit of the CPU address is set to 0 to form the
VGA address. So in text mode 3h, CPU address B8001h corresponds to
VGA address 0000h, plane 1, while CPU address B9234h corresponds to VGA
address 1234h, plane 0. Since LSB of the CPU address selects the plane
there's no need fiddle around with VGA registers to access video memory.

In the 256-colour graphics mode 13h the A0000h-AFFFFh range is mapped
to VGA memory, and like with the text modes this isn't a direct mapping,
"chain 4" mapping used instead. In this mapping the lowest two bits of
the CPU address determine the plane accessed, and are zeroed to obtain
the VGA addess. So in this mode CPU address A0003h is mapped to VGA
address 0, plane 3, while CPU address A1234h is mapped to VGA address
1234h, plane 0.

(Note the famous "Mode X" works by setting up the VGA registers to
display 256-colour graphics just like mode 13h does, except that the
"chain 4" bit isn't enabled. Instead video memory is accessed in the
same fashion as used by the 16-colour graphics modes, allowing access
to all 256kb of video RAM.)

Now this would seem exclude that your garbage writes to B8000h going to
video memory, because text mode write to B8000h would go VGA address
0000h, plane 0, the place a graphics mode 13h write to A0000h goes.
However that text mode mapping is no longer effect when in mode 13h,
and how writes to B8000h are mapped in that case is not entirely well
defined. I'd expect most VGA cards to ingore the writes, but there's
at least one VGA register configution where they could so somewhere.
The VGA Memory Map Select field has four possible values:

00b A0000h-BFFFFh
01b A0000h-AFFFFh
10b B0000h-B7FFFh
11b B8000h-BFFFFh

Note that there's one value, 00b, that maps the entire A0000h-BFFFFh
range to video memory. Unfortunately, what happens when you access memory
in the region B0000h-BFFFFh with this value selected doesn't seem to be
well defined in actual hardware.

One possible implementation is that access to B0000h-BFFFFh simply wraps
around to A0000h-BFFFFh, that is, CPU address bit 16 (A16) is simply
ingored by the VGA card. So a write to address B8000h (and A8000h) would
map to VGA address 8000h, right in the middle of mode 13h frame buffer.
The other is that the A16 bit is decoded and allows access to SuperVGA
memory (> 256kb). So a write to address B8000h would map to SVGA address
18000h, which is outside the mode 13h frame buffer.

Obviously if your PVGA card isn't a SuperVGA card and doesn't have more
256k then the later explaination wouldn't make sense. However even
then it's possible your card isn't 100% VGA compatible and uses some
other mapping that keeps your garbages writes away from the mode 13h
frame buffer.

The other alternative is that your garbage writes landed in system
memory, and I can't see how this could happen on actual hardware.
The memory controller has no idea what video mode the graphics card
is using and so can't dynamically change how it routes memory accesses
simply on that basis. For it to work the memory controller would have
to subtractively decode CPU memory accesses in the region B8000h-BFFFFh
to system RAM. That is, the memory controller would first try to peform
the access using a device bus (ISA, PCI, AGP, PCI-E, DMI, or HT) and if
that fails it would go to system memory instead.

I assume your 386SX system only has ISA slots and so your "PVGA" card
is an ISA card. In this case, I can't see this happening as there's no
reliable way to know whether an ISA bus transaction completed or not.
A write or read of a given memory location on the ISA bus can look the
same to the memory controller regardless of whether there's actually a
device on the bus that is decoding that memory location. (The device
can respond in various ways, like by asking the controller to wait until
its ready, but this isn't required. Even a read access can leave the
data bus unchanged.)

On PCI-based (including PCI-Express) systems, my understanding is this
can also never happen, but for a different reason. While PCI devices
(including AGP and PCI-Express devices) acknowledge bus cycles directed
at them, all PCI-based memory controllers I know of either positively
decode the entire A0000h-BFFFFh address range to a device bus, or
entirely to system memory. The later doesn't happen normal operations,
the one exception I know of is that it can potentially happen when the
CPU is in system management mode (SMM). There's no memory controller
configuration I've seen that would allow memory accesses in this range to
be subtractively decoded to system RAM. There's no reason to allow this,
indeed you'd never never want to use RAM that was subtractively decoded as
it would impose a huge latency penalty as the memory controller waits to
see if anything on the relatively slow device bus acknowleges the request.

So I think it's actually more likely that your 386SX/PVGA test case
actually wrote to video RAM. In any case, I think it's an unusual
case that its actually writing anywhere, and that's what my own testing
confirms. I tried various ATI cards (VGA Wonder XL, 3D Rage II+, Rage
128, Radeon 7200, Radeon 9550) and an NVIDIA card (TNT2 M64) on three
different systems (Pentium 4, Pentium 3 and Pentium MMX) and all gave
consistent results. Writes to B8000h when graphics mode 13h was active
all appeared to go nowhere.

Only under under emulated/virtualized enviroments did I see any difference
in behaviour. Under DOSBox and Windows 98 the writes did go somewhere,
virtualized RAM I assume. DOSBox also displayed different screens than
actual hardware during the test, indicating that it doesn't emulate the
VGA compatible memory mapping I described above. Under VirtualBox the
writes didn't go anywhere but the screens are also different than on
actual hardware.

Here's the code I used to perform the tests:

_TEXT SEGMENT PUBLIC WORD 'CODE'
ORG 100h

start:
; switch to each mode used in the test to ensure they all
; start in a "cleared" state

mov ax, 0003h
int 10h

mov ax, 0012h
int 10h

mov ax, 0013h
int 10h

; fill the mode 13h frame buffer with a pattern that
; should be easily recognizable in text mode

mov ax, 0a000h
mov es, ax
xor di, di
mov eax, 'a' OR 0a00h OR ('B' SHL 16) OR 40000000h
mov cx, 320 * 200 / 4
rep stosd

xor ax, ax
int 16h

; write a screenfull of words to B800:0000

mov ax, 0b800h
mov es, ax
mov ax, 'c' OR 0e00h
mov cx, 80 * 25 / 2
push cx
xor di, di
rep stosw
xchg ax, bx

xor ax, ax
int 16h

; check to see if any of the words written changed

xor si, si
pop cx
loop_check:
lods WORD PTR es:[si]
cmp ax, bx
jne fail
loop loop_check
fail:
push cx

; switch to mode 12h without clearing video memory
; this mode shows the most of video RAM of all
; standard VGA modes

mov ax, 0012h OR 80h
int 10h

xor ax, ax
int 16h

; switch to text mode without clearing the screen

mov ax, 0003h OR 80h
int 10h

xor ax, ax
int 16h

mov ax, 0003h
int 10h

mov dx, OFFSET pass_msg
pop cx
or cx, cx
jz passed
mov dx, OFFSET fail_msg
passed:
mov ah, 09h
int 21h

mov ax, 04c00h
int 21h

fail_msg:
DB 'comparison failed', 13, 10, '$'

pass_msg:
DB 'comparison passed', 13, 10, '$'

_TEXT ENDS

END start

--
l/ // Ross Ridge -- The Great HTMU
[oo][oo] rri...@csclub.uwaterloo.ca
-()-/()/ http://www.csclub.uwaterloo.ca/~rridge/
db //

Mateusz Viste

unread,
Nov 8, 2016, 5:12:20 AM11/8/16
to
Hi Ross,

Thanks for the extensive introduction into VGA internals :)

After reading your message I decided to double-check my results on the
386SX/PVGA I keep prisoner in my attic, using the same test program I
posted yesterday in msgid <58203f43$0$5421$426a...@news.free.fr>. One's
never too sure.

The results are... well, consistent with yours. It would appear I've
smoked too much dried PCB yesterday and didn't attach as much attention
to the "read back" part of the test (in fact, I was much more interested
in the "shared memory" aspect of the problem, and didn't look carefully
enough at the secondary question).

Anyway, today's observations on my 386SX/PVGA are the following:
- Writing to B800:0000 during video mode 13h does not distort the
screen's output
- When getting back to text mode *without* flushing VRAM, the pixel data
from the previous graphic mode shows up in console (in my test, lots of
'a' characters)
So far, same as what I claimed yesterday. Conclusion still the same - VRAM
is definitely shared, as I expected it to be. The change is this:
- The data that I wrote to B800:0000 during video mode *cannot* be read
back. My test writes a serie of integers from 0 to 15 into B800:0000, but
what I read back on my 386SX/PVGA is a serie of repeated '5' values. I
must have looked to hastily yesterday - sorry for the confusion!
I re-did the test several times, turning the PC off/on in between, and
the results is always the same - whenever I try to read from B800:0000
during video mode 13h, I get the byte value 5.

I also re-did my test on DOSEMU and DOSbox (just to be 100% sure), and
these are exactly the same as what I wrote yesterday. Meaning that the
only difference between real hardware and these emulators is that the
latter somehow preserve writes to B800:0000 during video mode, while the
former doesn't. An emulation glitch, it would appear.

regards,
Mateusz

Harry Potter

unread,
Nov 8, 2016, 6:33:17 AM11/8/16
to
I thank all of your input. I'm glad I can feasibly do what I want to do. :)

Steve

unread,
Nov 8, 2016, 3:34:19 PM11/8/16
to
Hi,

rri...@csclub.uwaterloo.ca (Ross Ridge) writes:
<Big Snip>
>Only under under emulated/virtualized enviroments did I see any difference
>in behaviour. Under DOSBox and Windows 98 the writes did go somewhere,
>virtualized RAM I assume. DOSBox also displayed different screens than
>actual hardware during the test, indicating that it doesn't emulate the
>VGA compatible memory mapping I described above. Under VirtualBox the
>writes didn't go anywhere but the screens are also different than on
>actual hardware.
>
>Here's the code I used to perform the tests:
<Snip>

Thanks for the code. Got it to run, after the usual stupidities,
and saw the same results as you.

Back in the old days a CGA card and a monochrome text card could
both be installed. And you could switch between them preserving
the output of each. They were separate cards, so that was easy.
So I wrote a program to try something like that on a VGA card.
Tested on Win 98, Win XP, a VDM, and DOS 6.22, three computers.
Same results on all. Interesting, but not too useful.

SCALL is a INT 21H using mnemonic EQUates in place of numbers.
Same functions as the ones you used.

PAGE ,132
TITLE Test VGA BIOS mapping.
NAME VIDTEST2

COMMENT |
8 November 2016
VidTest2: Try out mode 3 and mode 7 flipping. Which does not
seem to work. But memory is preserved...
|

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
.XCREF
.XLIST
INCLUDE DEFMS.ASM ; MACRO and MS-DOS definitions from Heath/Zenith software
.LIST
.CREF

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

CODE SEGMENT
ASSUME CS:CODE,DS:CODE
ORG 100H ; COM file opening
START:
; Switch to each mode used in the test to ensure they all
; start in a "cleared" state.

MOV AX,0003H
INT 10H

MOV AX,0007H
INT 10H

MOV DX,OFFSET Msg7
SCALL OUTSTR

XOR AX,AX
INT 16H ; Pause

; Write a screenfull of words to B800:0000 (color text mode area).
MOV DX,OFFSET Write3
SCALL OUTSTR

MOV AX,0B800H
MOV ES,AX
MOV AX, 'c' OR 0E00H
MOV CX, 80 * 25 / 2
PUSH CX
XOR DI,DI
REP STOSW
XCHG AX,BX

XOR AX,AX
INT 16H ; Pause

; Switch to mode 3 without clearing video memory
; to see if it worked as expected.

MOV AX,0083H
INT 10H

MOV DX,OFFSET Msg3
SCALL OUTSTR

XOR AX,AX
INT 16H ; Pause

; See if write works

MOV AX,0B800H
MOV ES,AX
MOV AX, 'c' OR 0E00H
MOV CX, 80 * 25 / 2
PUSH CX
XOR DI,DI
REP STOSW
XCHG AX,BX

MOV DX,OFFSET Write3
SCALL OUTSTR

XOR AX,AX
INT 16H ; Pause

; Write a screenfull of words to B000:0000 (mono text mode area).
MOV DX,OFFSET Write7
SCALL OUTSTR

MOV AX,0B000H
MOV ES,AX
MOV AX, 'z' OR 0700H
MOV CX, 80 * 25 / 2
PUSH CX
XOR DI,DI
REP STOSW
XCHG AX,BX

XOR AX,AX
INT 16H ; Pause

MOV AX,0087H ; Mode 7 without clearing memory.
INT 10H

MOV DX,OFFSET Msg7
SCALL OUTSTR

XOR AX,AX
INT 16H ; Pause

MOV AX,0003H
INT 10H

MOV AX,04C00H
SCALL EXIT

Msg3 DB ' Mode 3 $'
Msg7 DB ' Mode 7 $'
Write3 DB " Writing c's to Mode 3 screen area $"
Write7 DB " Writing z's to Mode 7 screen area $"
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CODE ENDS
END START

Regards,

Steve N.

Ross Ridge

unread,
Nov 12, 2016, 3:30:51 PM11/12/16
to
Steve <Bo...@Embarq.com> wrote:
> Back in the old days a CGA card and a monochrome text card could
>both be installed. And you could switch between them preserving
>the output of each. They were separate cards, so that was easy.

Well, there wouldn't be any switching as they'd be both be active at the
same time. This was an early form of multiple monitor support and was a
popular debugging setup. The debugger would run on the MDA display and
the program being debugged running on the CGA display. You could also do
with this an MDA and a EGA/VGA/SVGA card, though if the other card was
an ISA card you had to put it in an 8-bit slot to force it operate in
8-bit mode. (Which is why you used to see ISA motherboards with both
8-bit and 16-bit slots despite the fact that it makes no difference
whether an 8-bit card is in a 16-bit slot or not.)

Interestingly, modern memory controllers still support this configuration,
although in theory only, given the lack of ISA support in motherboards
these days. They have an option where MDA addresses/ports get directed
towards a different device bus than the CGA/EGA/VGA ones. So you could
have a MDA card (attached to a PCI-to-ISA bridge attached to a PCI-Express
to PCI bridge) working along side a modern CPU's integrated graphics or
the latest AMD/NVIDIA PCI-Express x16 card.

Ross Ridge
0 new messages