Mail Archives: djgpp/1997/01/01/16:01:10
I'm trying to use virtual screens in my graphics lib. As they
vary in size from 64k to several megabytes, I decided that using the dpmi
functions was the best way to go. Anyways, the buffer appears to
allocate properly, but when I try to write to it, I get a GPF. And if I
skip the writes and just free the buffer after allocating, I freeze the
computer. If anyone can explain what is wrong with how I'm doing this,
I'd appreciate it. Oh, I would have included a working program, but it
would have been excessively long, and I'm sure that the problem is in
either how I'm allocating memory, or how I'm accessing it....
// This function allocates a buffer to a size calculated from 'info', a
struct.
// In the class 'videoCard', both 'bufexists' and 'buffer' (which is
__dpmi_meminfo) are // members.
unsigned long videoCard::makeBuffer(_modeInfo *info)
{
if(bufexists==TRUE) // don't allocate the buffer twice...
return 0;
// Dividing the number of bits-per-pixel by 8 gives you bytes per
pixel... so I allocate
//enough mem for 24bit modes, I'm not supporting modes of less than
8bpp...
// I'm filling in the number of bytes I want here, as it says in the
docs...
buffer.size = info->xRes * info->yRes * (info->bitsPerPixel/8);
// 'buffer' isn't a pointer... It is declared as '__dpmi_meminfo buffer;'
if(__dpmi_allocate_memory(&buffer) == -1) { // allocate the buffer
error = NOMEM; return 0; }
__dpmi_lock_linear_region(&buffer); // lock it, so it won't get paged to
disk =)
bufexists = TRUE; // mark it as existing
// return it's address. Ok, is 'buffer.address' really what I want to be
returning to a
// pointer (unsigned char *p), or should I be converting this address in
some way
// first?
return buffer.address;
}
// this is called to free the buffer after we're done using it, it
freezes up the computer
bool videoCard::killBuffer()
{
if(bufexists==TRUE) { // if we've actually allocated it...
__dpmi_unlock_linear_region(&buffer); // unlock it. (do I need
to?)
if(__dpmi_free_memory(buffer.handle) == -1) // free it
return 0;
}
return 1;
}
// this flips the buffer to vga mem...
void flipToScreen(_modeInfo *info, unsigned char *bufptr)
{
unsigned long size = (unsigned long)info->xRes * (unsigned
long)info->yRes *
(unsigned
long)(info->bitsPerPixel/8);
// ok, I assume buffer::handle is a selector... is it? I tried looking
through the info files
// and the faq, but there wasn't any explanation. And if it isn't the
selector, how would
// I make one for my buffer?
movedata(buffer.handle, ((int)bufptr)&0xFFFFF, _dos_ds, 0xA0000,
size);
}
thanks,
aaron
- Raw text -