我试图在VGA dos程序中放入双缓冲,但在使用memcpy函数时似乎出现了问题。
我确信我分配了所需的内存,但它似乎不起作用。
这是程序:
#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, ®s, ®s);
}
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
工作是因为程序不会崩溃,缓冲区接受颜色,但memcpy似乎不工作,因为屏幕上什么都没有。
当我直接写入VGA地址时,它就起作用了。在(11,9(上会有一个粉红色像素,但在(10,9(中没有白色像素
您的问题是,您可能使用接近数据的模型进行编译,比如默认情况下数据指针接近的微小内存模型。近数据指针只能指默认数据段中的内容,VGA帧缓冲区位于该默认段之外。虽然您正确地将变量VGA
定义为远指针,但当您将此指针传递给memcpy
时,它会被转换为近指针,因为memcpy
将void *
作为第一个参数。由于您使用的是近数据模型,void *
是近指针类型。
要解决这个问题,您应该使用函数_fmemcpy
,它将void far *
指针作为参数,这样您的VGA
指针就不会转换为近指针。
您还应该注意编译器的警告。您的编译器应该用如下消息警告您这个问题:
Warning: test.c 24: Suspicious pointer conversion in function main
您还应该注意并修复关于在没有原型的情况下调用函数的警告,因为正确的原型化函数允许编译器警告可疑的指针转换,如上所述。