From: collins@blkbox (Chad R. Collins)
Subject: Re: Copying whole screens for Page Flipping
Organization: The Black Box, PO Box 591822 Houston, TX 77259-1822 
Date: Wed, 30 Dec 1992 03:25:32 GMT

baylor@ccwf.cc.utexas.edu (Baylor) writes:


>	Me and my finicky Pascal compiler can't get some code
>to work. I'm trying to page flip and to do it, i want to copy 
>everything from page 0 to page 1. Below is a hard-coded routine
>to copy all of page 0 to page 1, hoping of course page 1
>starts at 0a000:8000.
>	And it don't work - it sometimes does nothing (page 1
>stays the same) or else only icons with bit 0 set (like blue,
>gray purple colors) are copied, but when they copy they make 
>solid white icons. I assume somehow only bit 0 is being copied over,
>which is why page 2 only has black and white images on it.
>	I don't have the hang of switching planes, and since i 
>have to copy from a plane from dest to plane on source, i hope
>1 plane switch does tha plane switching for both source and dest.
>If any of you have any ideas about what i could look at, please 
>let me know.
>	Kinda makes me wish i had an amiga...




>Procedure Copy_Page; assembler;
>(* Updates global variable Vis_Page                 *)
>(* ES:DI - Destination (to)   DS:SI - Source (from) *)
>(* CX    - Plane Loop         CX    - Row Loop      *)
> const
>      ScreenWidth          = 320;
>      ScreenHeight         = 200;

>      Sequencer_Index      = $3C4;
>      Color_Plane_Index    = $02;
>      CurrentPlane : byte  = 8;

>      Screen_Offset        = $0A000;
>      ScreenBytes          = ScreenWidth div 8; (* Bytes per scanline *)
>      PlaneBytes           = ScreenBytes*ScreenHeight;
>      PlaneWords           = PlaneBytes div 2;
>      Page_1_Offset        = ScreenBytes*ScreenHeight;
>(* var
>    CurrentPlane : byte;*)
>  Asm
>     push ds
>     push es

>     cld

>     mov  CurrentPlane,8
>     mov  cx,4   (* Num Planes *)

>     mov ax,Screen_Offset
>     mov ds,ax

>     mov ax,Screen_Offset
>     mov es,ax

> @@Set_Address:
>     mov di,Page_1_Offset
>     xor si,si

>     @@Plane_Loop:
>         push cx           (* Save Plane Number *)

>         mov dx,Sequencer_Index    (* set plane *)
>         mov al,Color_Plane_Index
>         out dx,al
>         inc dx
>         mov al,CurrentPlane
>         out dx,al

>         mov cx,PlaneWords  (* copy that plane *)
>         rep movsw

>         shr CurrentPlane,1    (* next plane *)
>         pop cx                (* set cx back to planes *)

>         loop @@Set_Address

>     pop es
>     pop ds
>  End;
	Well- 1) I dont know assembly and 2) nor do I know Pascal so I
don't know EXACTLEY what you are doing, but it seems to me you are going
about the whole thing in the wrong way. You don't have to copy each
plane seperately... that is the advantage of a 32-bit VGA card, you get
to copy 4 bytes at a time. First, you need to set the Map Mask register
so that you write to all four planes and then do the normal block
memory move. Each time you read a byte from the video memory, each
plane's byte is loaded into the latch registers and then the latch
registers are written to the video memory. More than likely, the problems
you are having are due to the registers not being set right. I would
check and make sure the Bit and Map Mask registers are set up right.

Chad R. Collins
collins@blkbox.com

P.S.- this is the subroutine I use to choose the plane to write to...
it is written in C, but you should be able to translate it pretty
easily...

void select_plane(char plane)
{
        asm {
                mov dx, 0x3c4
                mov al, 2
                out dx, al
                inc dx
                mov al, [plane]
                out dx, al
        }
}

So, for plane one, set plane = 1, for plane two plane = 2, plane three 
plane = 4, plane four plane = 8... You can select multiple planes by
adding them toghther, so setting plane = 15 selects all four planes.

Newsgroups: rec.games.programmer