From: Shawn Hargreaves Newsgroups: comp.os.msdos.djgpp Subject: Re: [Allegro] Virtual Screen problem Date: Sun, 8 Jun 1997 13:53:12 +0100 Organization: None Distribution: world Message-ID: <+$187KA4sqmzEwhz@talula.demon.co.uk> References: <5n5eed$nar AT netnews DOT csie DOT nctu DOT edu DOT tw> NNTP-Posting-Host: talula.demon.co.uk MIME-Version: 1.0 Lines: 65 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk 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.