3

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)

alabdaly891
  • 159
  • 1
  • 8
  • Are you sure if you write somethings to VGA address it has any effect on screen? Eg. VGA[320*10] = 128; – Login Sep 18 '20 at 06:51
  • @Login I'm sorry I noted that now but yes the VGA address works just fine with all the 320*200 pixels – alabdaly891 Sep 18 '20 at 06:58
  • Things I'd try (just brainstorming here): use `calloc()` to zero initialize doublebuffer and test the result for `NULL`, use `memmove()` just for fun, move globals inside `main()`... exit *loudly*: `fprintf(stderr, "\aBUFFER MISMATCH!!!\a\n"); exit(1);` – pmg Sep 18 '20 at 07:03
  • Please [edit] and show also the code that works (the one that writes directly into the VGA memory). – Jabberwocky Sep 18 '20 at 07:04
  • 2
    _fmemcpy(...... – 0___________ Sep 18 '20 at 07:07
  • How many bytes per pixel? Faced this problem 25 years ago and it happened to be because one of the bytes was zero or something – Tarik Sep 18 '20 at 07:26
  • @Tarik every pixel is one byte holding a value from 0x00 to 0xFF and there is 320*200 pixel – alabdaly891 Sep 18 '20 at 07:51

1 Answers1

2

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.

Ross Ridge
  • 38,414
  • 7
  • 81
  • 112