> When you say a program would still need to set up flat real mode, I > suppose you mean that they still need a jump to protected mode and back > to initially setup the segment registers.
Yes. > However, I understood that HIMEM did something like establishing a > routine that was run whenever you tried to use an offset greater than > 0FFFFh together with a "real-mode-made" segment. This routine would > "trap" the event and handle the switch to protected mode and back, > keeping the segment base, but extending the limit to 4G, then returning > to the instruction that generated the exception. Am I right? Does this > really happen? If so, programs should not mind about their segments > being initially setup in real mode. No, I'm not aware of any Extended Memory Manager (XMM) that does such a thing. > I agree that using the EMS functions would make the interface lack of > good compatibility and would like to avoid that. What I don't want is to > do something that will not work if EMM386 happens to be running. I > believe that, while EMM386 is running and the system is in virtual-86 > mode, it is no longer possible to extend the segment limits to 4G and > they will always generate the exception. This makes me wonder how come > everything still seems to run properly (programs that use XMS) when EMM > is there. You're correct that with EMM386 (which sets up DOS to run in v86 mode), others can no longer set up flat real mode. I don't know whether such a thing as flat v86 mode is possible, but if it is you'd certainly have to work together with EMM386 to get there. I don't know whether Microsoft's HIMEM handles it the same way, but HIMEMX determines whether the CPU is currently in real or protected mode first. If it's in real mode, HIMEMX sets up flat real mode (it can be build to use protected mode instead) and does the XMS move itself. If it's in protected mode, HIMEMX simply calls Int15.87 (BIOS Move extended memory). Int15.87 is hooked by EMM386. EMM386 internally just catches this request and handles it with its protected mode code. Note however that EMM386 sets things up so anything runs inside protected mode all the time. v86 mode is just a fast emulation of real mode that runs in protected mode. > My driver is a set of functions that use 32-bit registers and runs > hooked on a single interrupt. Sometimes the caller will provide a > pointer to a buffer and the functions will fill these buffers, but also, > some very big tables have to be loaded, that can occupy as much as one > or two megabytes.. I could do moving parts of them to conventional > memory as needed, but it would be faster if I could access them directly > somehow. The driver leads with a sound interface sometimes and needs to > set up big buffers that, depending on the sound card, may have a fix > hardware address beyond the conventional and high memory limit. Is this some sort of mapped I/O space for the hardware, or do you actually have to allocate a buffer at this address? Also, doesn't the hardware work with physical 32-bit addresses? If that's the case, notice that in any protected mode environment (and flat real mode too?) memory might be remapped. For example, EMM386 maps extended memory into the UMA to provide UMBs for the v86 mode DOS. Since the physical address used by the hardware still accesses the ROM or RAM that was in the UMA before EMM386 remapped UMBs, access to EMM386 UMBs with physical addresses doesn't work. Potentially extended memory could be remapped too. > Basically, the driver may return pointers to these areas, but could also > copy the data to a buffer provided by the caller. > Do you think I should write the functions like pure real-mode code > that accesses HIMEM XMS functions as needed to move the data? Would > that be entirely compatible with real-mode- as well as DPMI-applications > calling the functions? Yes, using HIMEM exclusively is compatible with both real mode and DPMI applications. That would of course require the user to load some HIMEM program, but I think that isn't too restricting. There aren't many reasons you wouldn't want to load any HIMEM. Note that if you lock your XMS memory block (XMS function 0Ch), HIMEM returns the linear 32-bit address of that block. DPMI applications can benefit from locking the block because you can provide them the linear address (as well as the XMS handle). This linear address can then be used in the DPMI environment to access the memory block directly. (For this, the DPMI application allocates a LDT descriptor (Int31.0000) and sets its base (Int31.0007) to the provided linear address as well as the limit (Int31.0008) to one large enough to access the memory block.) > If so, how should I handle the events when I need to read or write in a > fixed extended memory area? You're right, this can't be handled with XMS functions. You'd either have to set up your own protected mode/flat real mode/VCPI/DPMI environment (depending on whether an EMM or DPMI host is loaded) to access this memory, or use Int15.87. As mentioned, proper Int15.87 handling is provided by an installed EMM and your BIOS should provide it otherwise. (Consider that EMM's Int15.87, DPMI and VCPI only allow access to "remapped" memory using the linear address. VCPI might allow you to see how memory is remapped, though.) In case you actually have to allocate a buffer at that fixed address, your driver has to request, lock, resize and free XMS memory blocks to try allocating a block which returns the correct (linear) address when locked. > Is it better to always ask the caller to provide buffers or is it > more efficient (and safe) to return pointers to the buffers? In some > cases, the problem is that one buffer is to be used by many applications > (i.e.: a running program and a couple of TSRs in memory) and having the > caller create a buffer would mean the driver would have to update > several identical buffers instead of getting all tasks refer to the same > one. That would not be practical and would use up more memory. If the buffer is updated by your driver only (i.e. the applications aren't allowed to write to the buffer, not even by sending requests to the driver), then it's better to use a single buffer which is provided to the applications by the driver. Otherwise, every application should use its own buffer because with a single buffer you might run into reentrancy problems. (I.e. after one application requests something from the driver but isn't finished using the data, another application requests something else and that second request overwrites the data the first application is still using.) Regards, Christian ------------------------------------------------------------------------------ Come build with us! The BlackBerry(R) Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9 - 12, 2009. Register now! http://p.sf.net/sfu/devconference _______________________________________________ Freedos-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/freedos-devel
