Mail Archives: djgpp/1997/06/08/10:49:07
Chuang Li-chung writes:
> I have declared a screen of resolution 320x200 with 320x400 virtual
> screen, but when I executed the following funcion, it just return a
> mass of junk! ( this can be tested with Allegro example 2 )
>
> void move_block() {
> unsigned long waddress, raddress;
> _farsetsel(screen->seg);
This isn't anything to do with your problem, but incidentally you don't
need the _farsetsel() function if you are using movedata(). It sets the
selectors itself: you only need to use _farsetsel() if you are then
going to call the _farnspeek?() and _farnspoke?() routines.
> raddress = bmp_read_line(screen, now_y);
> waddress = bmp_write_line(screen, 0);
> movedata(screen->seg, raddress, screen->seg, waddress, SCREEN_W*SCREEN_H);
This code would be correct in a graphics mode with linear video memory
(VGA 13h or VBE 2.0 with a linear framebuffer), but it won't work for
banked SVGA modes or mode-X (since you are using a 320x400 virtual
screen, I assume that you are in mode-X here).
If you were running in an SVGA mode, this code is very nearly correct
except that you are assuming video memory is contiguous from one line to
the next, which isn't usually the case. You are treating all the video
memory from the start addresss up to SCREEN_W*SCREEN_H as a single
block, but you can only safely copy a block of SCREEN_W pixels, and
should then call the bmp_read_line() and bmp_write_line() functions
again to get the address of the next line of video memory (this may be
at a totally different location, and those functions also sometimes need
to alter the hardware bank select registers in your graphics card).
In mode-X, things get even more complicated :-) There are four planes of
video memory, and a single memory address is used to access four
different pixels. Your waddress pointer can refer to the first, second,
third, or fourth pixel on the screen (or even to all of them at once!)
depending on how you have set the VGA write enable flags. Similarly,
waddress+1 refers to the fifth, sixth, seventh, and eighth pixels, etc.
To specify which plane you want to access, write a four bit mask to
index #2 on port 0x3C4. To enable plane #n (which will cause writes to
the first memory address of the screen to affect pixel #n, writes to the
second address to affect pixel #n+4, etc), call:
outportw(0x3C4, (0x100<<(n&3))|2);
You can also set more than one bit in this mask: if you call
outportw(0x3C4, 0x0F02), whenever you write a single byte to video
memory it will be copied into all four planes (this is quite a handy
feature for writing fast graphics code!).
The plane to be used for reading mode-X memory is selected by index #4
of port 0x3CE. To select plane #n, call:
outportw(0x3CE, ((plane&3)<<8)|4);
Mode-X coding is way off topic for this group, though! For a really good
discussion of the issues involved, checkout the articles Abrash wrote
for DDJ (these can be found on x2ftp.oulu.fi).
--
Shawn Hargreaves - shawn AT talula DOT demon DOT co DOT uk - http://www.talula.demon.co.uk/
Beauty is a French phonetic corruption of a short cloth neck ornament.
- Raw text -