cdosvga

memcpy doesn't do anything


I was trying to put double buffering into my VGA dos program but it seems that there is a problem when I use the memcpy function.

I'm sure that I allocate the required memory but it doesn't seem to work.

Here is the program:

#include <dos.h>
#include <string.h>
unsigned char* doublebuffer;
unsigned char far* VGA = (unsigned char far*) 0xA0000000L;
void setmode(int mode)
{
   union REGS regs;
   regs.h.ah = 0x0;
   regs.h.al = mode;
   int86(0x10, &regs, &regs);
}

void main()
{
    doublebuffer =(unsigned char *) malloc(320*200);

    setmode(0x13);
    VGA[9*320+11] = 0x41;
    doublebuffer[9*320+10] = 15;
    if(doublebuffer[9*320+10]  != 15)
    {
     exit(1);
    }
    memcpy(VGA, doublebuffer, 320*200);
    getch();
}

malloc works since the program doesn't crash and the buffer accepts the color but memcpy doesn't seem to work since there is nothing on the screen.

When I write into the VGA address directly it works. there would be a pink pixel on (11, 9) but no white pixel in (10, 9)


Solution

  • Your problem is that you're presumably compiling using a near data model, like the tiny or small memory model where data pointers are near by default. Near data pointers can only refer to things in the default data segment, and the VGA frame buffer is located outside of this default segment. While you correctly define the variable VGA as a far pointer, when you pass this pointer to memcpy it's cast into a near pointer because memcpy takes a void * as is first argument. Since you're using a near data model void * is a near pointer type.

    To fix this problem you should use the function _fmemcpy instead which takes void far * pointers as arguments, and so your VGA pointer won't be converted to a near pointer.

    You should also pay attention to compiler warnings. Your compiler should have warned you about this problem with a message like the following:

    Warning: test.c 24: Suspicious pointer conversion in function main
    

    You should also heed and fix warnings about calling functions without prototypes, as correctly prototyped functions are what allows the compiler to warn about suspicious pointer conversions like above.