delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2001/10/14/12:19:07

From: Felix Natter <f DOT natter AT ndh DOT net>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Windows 2000: __dpmi_physical_address_mapping fails
Date: 14 Oct 2001 16:40:28 +0200
Organization: Customer of Pironet NDH AG, Germany
Lines: 210
Message-ID: <87k7xz9tzm.fsf@mybaby.home.felix>
References: <87d73r96yo DOT fsf AT mybaby DOT home DOT felix> <8484-Sat13Oct2001145006+0200-eliz AT is DOT elta DOT co DOT il>
NNTP-Posting-Host: port226.bonn.ndh.net
Mime-Version: 1.0
X-Trace: passat.ndh.net 1003075729 29978 195.94.93.226 (14 Oct 2001 16:08:49 GMT)
X-Complaints-To: abuse AT ndh DOT net
NNTP-Posting-Date: 14 Oct 2001 16:08:49 GMT
User-Agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/20.7
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

"Eli Zaretskii" <eliz AT is DOT elta DOT co DOT il> writes:

> > From: Felix Natter <f DOT natter AT ndh DOT net>
> > Newsgroups: comp.os.msdos.djgpp
> > Date: 13 Oct 2001 12:20:47 +0200
> > 
> > with code like this:
> > 
> >   __dpmi_meminfo meminf;
> >   meminf.address = vbe_modeinfo.PhysicalBasePtr;
> >   meminf.size	= screensize;
> >   if (__dpmi_physical_address_mapping(&meminf) ==	- 1)
> >     => error
> > 
> > "__dpmi_physical_address_mapping" fails on Windows 2000 (both in the DOS
> > box or when I select Dos on startup).
> > 
> > I am using cwsdpmi (the version that comes with djdev2.02).
> 
> Please post a minimal complete program which can be compiled and which
> exhibits this behavior.  (The main detail you left out are the values
> of the base address and the size you pass to __dpmi_physical_address_mapping.)

the values are computed from getVBEModeInfo(mode) (see below).
The struct is defined in the header-file
(http://www.ndh.net/home/natter/vbetwo.h)

I will try a small program on Monday.

here is the complete code of the function that fails:

bool openVBE(int width,	int height,	unsigned char bpp	= 8)
{
  if (!initVBE())
    {
      printf("\nNo VBE 2.0 loaded.\n");
      abort();
    }
  int modeidx	= 0;
  unsigned short mode;
  while	(1)
    {
      mode = AvailableModes[modeidx++];
      if (mode ==	0xFFFF)
	return false;
      if (getVBEModeInfo(mode) == false)
	continue;
      if (vbe_modeinfo.XResolution != width)
	continue;
      if (vbe_modeinfo.YResolution != height)
	continue;
      if (vbe_modeinfo.BitsPerPixel	!= bpp)
	continue;
      break;
    }
  getBDA8x8charpattern();
  settextsize(8, 8);
  xres = vbe_modeinfo.XResolution;
  yres = vbe_modeinfo.YResolution;
  BPP =	vbe_modeinfo.BitsPerPixel;
  CLIP_LEFT = 0;
  CLIP_TOP = 0;
  CLIP_RIGHT = xres - 1;
  CLIP_BOTTOM = yres - 1;
  BytesPerScanline = vbe_modeinfo.BytesPerScanline;
  unsigned long screensize = BytesPerScanline * yres;
  if (screensize % 4)
    handleError(ErrorMessage("Screensize [PARAM1] isn't dword-aligned.", "", screensize));
  offscreen =	(char*)xmalloc(screensize);
  screensize_dword = screensize	/ 4;
  if (sizeof(Scanline) != 32)
    handleError(ErrorMessage("Compiler DOES pad 'Scanline's at the end!!!", "", sizeof(Scanline)));
  scanline_list = (Scanline*)xmalloc(yres * sizeof(Scanline));
  contrast_lookup = (unsigned char*)xmalloc(0x100);
  __dpmi_meminfo meminf;
  meminf.address = vbe_modeinfo.PhysicalBasePtr;
  meminf.size	= screensize;
  if (__dpmi_physical_address_mapping(&meminf) ==	- 1)
    handleError(ErrorMessage("physical-address mapping failed",	"", meminf.address));
  LFB_linear_address = meminf.address;
  LFBselector	= __dpmi_allocate_ldt_descriptors(1);
  if (LFBselector == -1)
    handleError(ErrorMessage("allocating ldt-descriptors failed"));
  if (__dpmi_set_segment_base_address(LFBselector, LFB_linear_address) ==	-1)
    handleError(ErrorMessage("setting selector base address to [PARAM1] failed", "", LFB_linear_address));
  if (__dpmi_set_segment_limit(LFBselector,	meminf.size) == -1)
    handleError(ErrorMessage("setting selector limit to [PARAM1] failed", "", meminf.size));
  __dpmi_regs	regs;
  regs.x.ax =	0x4F02;
  regs.x.bx =	mode | VBE_MODEFLAG_LFB;
  safe_int(0x10, &regs);
  if (regs.x.ax != 0x004F)
    return false;
  //if ((LogicalPixelsPerScanline = getLogicalScanlineWidthPixels()) == 0)
  //      handleError(ErrorMessage("Couldn't get logical scanline-width."));
  LogicalBytesPerScanline	= BytesPerScanline;
  //if (setLogicalScanlineWidthPixels(LogicalPixelsPerScanline = xres) != 1)
  //      handleError(ErrorMessage("Couldn't set logical scanline-width.", "", xres));
  //if (getDisplayStart(&DisplayStartX, &DisplayStartY) != 1)
  //      handleError(ErrorMessage("Couldn't get display-start."));
  DisplayStartX = 0;
  DisplayStartY = 0;
  //if (setDisplayStart(DisplayStartX, DisplayStartY) != 1)
  //      handleError(ErrorMessage("Couldn't set display-start.", "", DisplayStartX, DisplayStartY));
  /*
    the following is taken from someone's vesa-driver for s3-cards;
    I didn't notice any difference back when I had an s3-card
   */
  //come_on_push_it(); // S3 (and only S3!) S-P-E-E-D-U-P
  updatecolors();
  return true;
};

and here are the functions that are called:

static void safe_int(int vect, __dpmi_regs* pregs)
{
  if (__dpmi_int(vect, pregs) != 0)
    handleError(ErrorMessage("Error issuing RM-int (dpmi failed)", "", vect));
};

void saveScreen(const char* szfilename, char* pal)
{
  FILE* scr = fopen(szfilename, "wb");
  short x_res = (short)xres, y_res = (short)yres;
  char curpal[0x300];
  if (pal == NULL)
    {
      getpal(curpal);
      fwrite(curpal, 0x300, 1, scr);
    }
  else
    fwrite(pal, 0x300, 1, scr);
  fwrite(&x_res, sizeof(short), 1, scr);
  fwrite(&y_res, sizeof(short), 1, scr);
  fwrite(offscreen, screensize_dword, 4, scr);
  fclose(scr);
};

static bool initVBE()
{
  __dpmi_regs	regs;
  strncpy(vbe_info.VESASignature, "VESA", 4);
  dosmemput(&vbe_info, sizeof(VBEINFO), __tb);
  regs.x.ax = 0x4F00;
  regs.x.es = __tb / 16;
  regs.x.di = 0x0000;
  safe_int(0x10, &regs);
  dosmemget(__tb, sizeof(VBEINFO), &vbe_info);
  if (regs.x.ax != 0x004F	|| vbe_info.VBEVersion < 0x0200)
    return false;
  int modelist_physical =	(vbe_info.VideoModePtrSegment	* 16)	+ vbe_info.VideoModePtrOffset;
  int lenbytes = 0;
  unsigned short word;
  do
    {
      dosmemget(modelist_physical +	lenbytes, 2, &word);
      lenbytes +=	2;
    } while (word != 0xFFFF);
  AvailableModes = (unsigned short*)xmalloc(lenbytes);
  dosmemget(modelist_physical, lenbytes, AvailableModes);
  regs.x.ax =	0x4F0A;
  regs.h.bl =	0x00;
  safe_int(0x10, &regs);
  VBE_PM_Interface*	vbe_PMI = (VBE_PM_Interface*)xmalloc(regs.x.cx);
  dosmemget((regs.x.es * 16) + regs.x.di, regs.x.cx, vbe_PMI);
  PMI_setDisplayStart = (void*)((char*)vbe_PMI + vbe_PMI->setDisplayStart);
  PMI_setPrimaryPalette =	(void*)((char*)vbe_PMI + vbe_PMI->setPrimaryPalette);
  return true;
};

static bool	getVBEModeInfo(unsigned	short	mode)
{
  __dpmi_regs	regs;
  regs.x.ax =	0x4F01;
  regs.x.cx =	mode;
  regs.x.es =	__tb / 16;
  regs.x.di =	0x0000;
  safe_int(0x10, &regs);
  dosmemget(__tb, sizeof(VBE_MODEINFO), &vbe_modeinfo);
  if (regs.x.ax != 0x004F	|| !(vbe_modeinfo.ModeAttributes & vbeModeAvailablewithLFB))
    return false;
  else
    return true;
};

 
> Also, how exactly does it fail? do you get -1 from the function?  If
> not, please tell the details about the failure.

yes, -1.

> > does a more recent version of cwsdpmi fix this or is there another
> > workaround ?
> 
> The latest CWSDPMI does indeed fix a subtle problem with this DPMI
> function, but CWSDPMI has nothing to do with running your program on
> Windows, only on DOS.  So it's not at all clear that this is a CWSDPMI
> issue.

the problem occurs both in the "DOS-Box" and when I boot DOS
(the version of DOS that comes with Windows 2000).
I will try to use cwsdpmi 5 on Monday.

-- 
Felix Natter




- Raw text -


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