delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/07/22/09:20:26

Xref: news2.mv.net comp.os.msdos.djgpp:6248
From: bcalves AT access2 DOT digex DOT net ()
Newsgroups: comp.os.msdos.djgpp
Subject: [Q] VBE/DJGPP mem. access
Date: 22 Jul 1996 05:28:30 GMT
Organization: Express Access Online Communications USA: 800-969-9090
Lines: 106
Message-ID: <4sv3hu$b3g@news3.digex.net>
NNTP-Posting-Host: access2.digex.net
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

Hi all,

I'm having some difficulty with my simple VBE test program.
My C program initializes 640x480x8bpp, packed pixel, linear 
framebuffer mode. Unfortunately, I seem to be unable to
write to said framebuffer. I think the problem may lie in how
I'm trying to gain access to the framebuf with dpmi. 

I've tried both near and far pointer techniques as per various 
tutorials/faqs I've seen, but the screen remains blank (except for
garbage when I don't set the memory-clear bit on the mode set 
function). Could someone please suggest what I might be doing wrong 
in the attached program??

Incidentally, the program runs without returning errors or faulting.
For what it's worth, I'm using UniVBE, QEMM's QDPMI, and a Diamond 
Edge 3D 3400XL. Do I need a newer DPMI implementation? My QDPMI
came with QEMM 7.

Thanks in advance,
Brian

--------Code Follows----------

#include <conio.h>
#include <dos.h>
#include <go32.h>
#include <dpmi.h>
#include <sys/farptr.h>
#include <iostream.h>
#include "vbe.h"

int main()
    {
    __dpmi_meminfo meminfo;
    __dpmi_regs r;
    CVBEMode *mode;
    uint linear_address;
    uchar *videoptr;
    int width, height, error, i;

    error = 0;


    // GET INFO FOR MODE 257 (640x480x8bpp, packed pixel, linear frame buf)
    mode = new CVBEMode(257);		// CVBEMode wraps the GetModeInfo func
    width = mode->XRes();		// I'm printed out all the CVBEMode 
    height = mode->YRes();		// data and it appears to be valid.


    // GET ADDRESS OF FRAME BUFFER
    meminfo.size = width * height;
    meminfo.address = (unsigned long int)mode->PhysBasePtr();
    __dpmi_physical_address_mapping(&meminfo);
    linear_address = meminfo.address;

    // The physical base ptr returned (above) from VBE is 0xe1100000
    // The resulting linear address was 0x8???????
    // Do those values set off alarms with anyone?


    // THIS IS FROM A TUTORIAL I FOUND
    videoptr = (unsigned char *)0x0;
    short our_global_selector = __dpmi_allocate_ldt_descriptors(1);
    __dpmi_set_segment_base_address(our_global_selector, linear_address);

    // THEN I ADDED THIS WHEN _farpokeb (BELOW) CAUSED SEG-FAULTS
    __dpmi_set_segment_limit(our_global_selector, width*height);


    // INIT MODE
    r.x.ax = 0x4F02;
    r.x.bx = 0xc000 | mode->ModeNum();
    __dpmi_int(0x10, &r);
    if (r.x.ax & 0xff00) error |= 0x1;


    // DISPLAY A FEW COLORFUL, HORIZONTAL BARS
    if (!error)
        {
        for (i=0; i<256; i++)
            {
            _farpokeb(our_global_selector, (uint)(videoptr + 100*width+i), i);
            _farpokeb(our_global_selector, (uint)(videoptr + 101*width+i), i);
            _farpokeb(our_global_selector, (uint)(videoptr + 102*width+i), i);
            _farpokeb(our_global_selector, (uint)(videoptr + 103*width+i), i);
            _farpokeb(our_global_selector, (uint)(videoptr + 104*width+i), i);
            }
        }
    getch();


    // RESTORE TEXT MODE
    r.x.ax = 0x3;
    __dpmi_int(0x10, &r);


    // EXIT
    if (error)
        cout << "Error:  0x" << (hex) << error << (dec) << endl;
    else
        cout << "No error" << endl;
    delete mode;
    }

--------End Code---------

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019