tcamp@dukeac.UUCP (Ted A. Campbell) (07/27/89)
For the next version of the "Space Flight Simulator" (posted recently
to comp.binaries.ibm.pc) I need a faster EGA/VGA memory copy routine.
The program utilizes a form of animation in which I write to one page,
switch it into visual memory, write to the other page, switch it in,
and so forth. At each switch, however, I have to update the new "active"
page by copying the entire contents of the previous active page to it.
Currently, I'm accomplishing this by writing the entire page out to
a buffer in user-accessible RAM (about 128k), then writing the whole
buffer back to the other page. Obviously, this wastes a great deal
of time for each screen update.
It should be possible to copy one page to the other. The problem is
that in the mode I'm using (640x350 16 color on both EGA and VGA)
the memory is divided into four planes, each of which would have to
be copied. Based on the best information I have had to date, I thought
that the following loop would accomplish this task:
for ( i = 1; i < 10; i *= 2 )
{
outp( 0x3CE, 0x04 ); /* set read map */
outp( 0x3CF, i ); /* to plane 'i' */
outp( 0x3C4, 0x02 ); /* set write map */
outp( 0x3C5, i ); /* to plane 'i' */
memcpy( (char *) 0xa0000000, /* copy to here */
(char *) 0xa8000000, /* from here */
(size_t) 0x8000 ); /* this many bytes */
}
But this doesn't work and I'm not even sure why: some copying is being
done, but apparently colors are getting mixed up, and eventually the
bit patterns are lost.
If any experienced EGA/VGA programmers out there can suggest a fast
way to accomplish this task, I'd be very appreciative.
Ted A. Campbell
tcamp@dukeac.ac.duke.edu
cb@sequoia.UUCP (Christopher D. Brown) (07/28/89)
In article <1495@dukeac.UUCP> tcamp@dukeac.UUCP (Ted A. Campbell) writes: ... > for ( i = 1; i < 10; i *= 2 ) > { > outp( 0x3CE, 0x04 ); /* set read map */ > outp( 0x3CF, i ); /* to plane 'i' */ > outp( 0x3C4, 0x02 ); /* set write map */ > outp( 0x3C5, i ); /* to plane 'i' */ > memcpy( (char *) 0xa0000000, /* copy to here */ > (char *) 0xa8000000, /* from here */ > (size_t) 0x8000 ); /* this many bytes */ > } > >But this doesn't work and I'm not even sure why: some copying is being ... Close. Try the following ... for ( z = 0; z < 4; ++z ) { outp( 0x3CE, 0x04 ); /* set read map */ outp( 0x3CF, z ); /* to plane 'i' */ outp( 0x3C4, 0x02 ); /* set write map */ outp( 0x3C5, 1 << z ); /* to plane 'i' */ memcpy( (char *) 0xa0000000, /* copy to here */ (char *) 0xa8000000, /* from here */ (size_t) 0x8000 ); /* this many bytes */ } chris brown Net: cb!execu@cs.texas.edu Voice: (512) 346-4980
everett@hpcvlx.HP.COM (Everett Kaser) (07/28/89)
When writing to EGA/VGA memory, you have to do a read first, even though you don't use the data, then do the write. The read latches the current video RAM data into internal latches in the video controller, then when you do the write, the video controller can combine the two according to the current replacement rule. If you don't do the read first, your write data is getting combined with whatever garbage is in the internal latches. Hence, I don't think you can use memcpy. I could be all wet, but this is what I've found in the little bit of EGA programming I've done. Everett Kaser "Your thoughts create your reality." !hplabs!hp-pcd!everett everett%hpcvlx@hplabs.hp.com