From: Felix Natter 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 Content-Type: text/plain; charset=us-ascii 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" writes: > > From: Felix Natter > > 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, ®s); 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, ®s); 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, ®s); 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, ®s); 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