brent@well.sf.ca.us (Brent Southard) (12/22/90)
I've been successful so far in my less adventurous forays into the DPMI forest (real mode interrupt simulation, real mode far calls, etc.), but now I'm finding my paths blocked by a wall of confusing, if not missing, documentation. I'm working on our Windows application, which does a considerable amount of hardware fiddling, and trying to expand it's memory handling capabilities. I need to work with large (1-5 megabyte) blocks of memory containing scanned image data. Because of earlier limitations of DOS and Windows, I had limited our data handling to EMS memory allocations. With the advent of Windows 3.0, XMS, and DPMI, I should be able to work with large contiguous memory blocks now, without the overhead of EMS. Now, you may be thinking I don't really need truly contiguous memory blocks. Not so. You see, I am working with some scanner hardware which wants to transfer, via DMA, (possibly) megabytes of data to an extended memory address. The transfer can not be broken up by any time span longer than it takes to reset the DMA hardware for the next transfer. Therefore, any memory block I allocate must meet the following criteria, at least at the time of DMA transfer: 1. The actual, physical, real, hardwired address of the memory must be beyond the 1 megabyte boundary, at least when locked. 2. The memory must be physically contiguous, or DMA will really have fun with the system. 3. The memory must be page locked (in enhanced mode). Well, it looked to me like a perfect application for XMS memory. Well, I put together a little test winapp to play with XMS EMBs (extended memory blocks). After determining that XMS is installed, and retrieving the control function's address (all via DPMI in enhanced mode), I decided to try to allocate the biggest block available. Calling the Query Free Extended Memory function (08h) revealed that I had a total of 4096K (4MB) XMS memory with the largest block free 2048K (2MB). This was a little surprising since I have a 4 megabyte (i.e. 3MB extended) system, so I'm guessing that the XMM is including virtual (disk) memory in its numbers. Well, I tried to allocate that 2MB block using the Allocate Extended Memory Block function (09h), and got back an error, BL==A0, which implies that ALL extended memory is allocated. Huh? I tried halving my request, and it succeeded. What gives? Now, let's say I didn't have the afore mentioned allocation problem. I'm still a little worried that XMS may allocate virtual memory -- what happens when I need to page lock? What are my alternatives? If I use GlobalAlloc() to allocate a big block of memory, will it be guaranteed to be contiguous, page lockable, and in the extended memory address region? If so, which functions do I use to get the true physical (hardware) address to pass to the scanner driver (for DMA)? Now that the questions are dealing more with DPMI than XMS, could someone clarify the terms 'physical' versus 'linear' as used in the DPMI spec? How is each type addressed, i.e. selector:offset or 32-bit address? My guess is that the DMA comtroller needs the 'linear' address... I'd appreciate any experienced answers I can get, since I'm in the middle of some code changes, and I can't wait for OnLine or the next issue of MSJ, whichever comes first. I will consider posting a summary of my knowledge if enough is gained. Thanks, Brent Southard ImageTech Corp. (313) 353-7900 -- brent southard (313) 656-8349 | usenet: ...!well!brent ImageTech Corp (313) 362-3141 | "When frog licking is outlawed, only outlaws will lick frogs."
mojo@netcom.UUCP (Morris Jones) (12/22/90)
brent@well.sf.ca.us (Brent Southard) writes: > Well, I tried to allocate that 2MB block using the >Allocate Extended Memory Block function (09h), and got back an error, BL==A0, >which implies that ALL extended memory is allocated. Huh? I tried halving my >request, and it succeeded. What gives? Brent, it's possible that Windows won't allocate more than a meg of 16-bit memory because of limits involving 16-bit pointer arithmetic and selectors. So here's an alternative: Look at Appendix E of the SDK. Use the 32-bit memory allocation functions. I have succesfully allocated much larger chunks of memory using the Global32Alloc() function. You can refer to the memory with 16-bit pointers if you need to by getting a 16-bit alias with Global16PointerAlloc(). As far as insuring that the memory is contiguous and page locked ... ... I'm afraid you're on your own. But if you find a way to do it, I'd certainly like to hear about it. Mojo Caere Corp. netcom!mojo@apple.com -- mojo@netcom.UUCP Site Coordinating Instructor, San Jose South Morris "Mojo" Jones Skilled Motorcycling And Rider Training (S.M.A.R.T.) Campbell, CA 800-675-5559 ... 800-CC-RIDER ... 408-423-2212 AA4KB @ N6LDL.#NOCAL.CA.USA.NA / aa4kb.ampr.org / netcom!mojo@apple.com