www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1995/09/12/14:11:32

Date: Tue, 12 Sep 95 11:04 MDT
From: mat AT ardi DOT com (Mat Hostetter)
To: larsen AT sunset DOT cs DOT utah DOT edu
Subject: Re: DPMI question
Newsgroups: comp.os.msdos.djgpp
References: <430m0v$n5 AT magus DOT cs DOT utah DOT edu>
Cc: djgpp AT sun DOT soe DOT clarkson DOT edu

>>>>> "Steve" == Steve Larsen <larsen AT sal DOT cs DOT utah DOT edu> writes:

    Steve> I am writing some VESA 2.0 routines.  One thing I need to
    Steve> be able to do is access a linear segment of memory (a
    Steve> linear framebuffer).  I have figured out how to get the
    Steve> physical address from the VBE, allocated a selector, and
    Steve> set the base and limit of the selector as described in
    Steve> numerous places.  Now I need to figure out how to use all
    Steve> this info to do what I want :) Basically, I want to do a
    Steve> memcpy from my offscreen buffer to some mapped memory and
    Steve> have it appear on the screen (either in C or asm, either is
    Steve> fine).  Also, I would rather not use the nearptr's hack.
    Steve> Any help would be greatly appreciated.


Our Mac emulator does exactly the same thing.  Here's the code I use
on DPMI 0.9 servers (on DPMI 1.0 servers I map linear frame buffers
into our address space and use near ptrs to reference them; that
requires different code).  This routine will return a selector for a
specified range of physical memory, or -1 if it failed (no warranty on
this code, etc.).  You can pass that selector to `movedata' to copy
stuff to the screen very quickly.


static int
selector_for_phys_mem (uint32 base_addr, uint32 num_bytes)
{
  int sel;
  uint32 seg_lim;
  __dpmi_meminfo minfo;

  /* Allocate a descriptor. */
  sel = __dpmi_allocate_ldt_descriptors (1);
  if (sel == -1)
    return -1;

  seg_lim = ((num_bytes + 4095) & ~4095) - 1;

  /* Map the physical memory into linear address space. */
  minfo.handle  = 0;		/* unused */
  minfo.size    = seg_lim + 1;
  minfo.address = base_addr;
  if (__dpmi_physical_address_mapping (&minfo) != 0)
    return -1;

  if (__dpmi_set_segment_base_address (sel, minfo.address) == -1)
    return -1;
  if (__dpmi_set_segment_limit (sel, seg_lim) == -1)
    return -1;

  return sel;
}


    Steve> P.S.  Another quick one.  Today while trying to get this
    Steve> working, I was hitting an interesting problem.  I was
    Steve> getting a protection fault while loading a segment register
    Steve> (es).  Are the segment registers somehow protected while in
    Steve> protected mode?

Yes.  Only load legitimate selector values into segment registers.

-Mat

- Raw text -


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