/////////////////////////////////////////////////////////////////////////////// / / / DPMILD16 - load NE 16-bit binaries / / / /////////////////////////////////////////////////////////////////////////////// 1. Introduction DPMILD16 can load NE-executables as 16-bit DPMI clients. The loader supports applications and dlls. Beyond that, it exports some standard KERNEL functions to be used by the application so that you may be able to use a standard 16-bit C programming development environment. GUI functions are not supported. A library called KERNEL16.LIB is included. It contains references to all functions that DPMILD16 exports. DPMILD16.EXE contains only 16-bit code and therefore should run on 80286 cpus. 2. Memory Model The memory model of DPMILD16.EXE is essentially the same as for 16-bit NE binaries in Windows 3.X: each segment gets a selector and segments are limited to a maximum size of 64 KB (this is not exactly true because there is support for huge segments, which cover several segments. DPMILD16 can handle this case). DOS memory should be mainly free and can be allocated through DPMI function 0x0101 or through DPMILD16 function GlobalDosAlloc(), which behaves like its windows pendant. Segment attributes are supported a bit differently as in Windows 3.X. PRELOAD segments are always loaded before the application starts, but LOADONCALL segments are just loaded when the application touches them. In Windows 3.X this is true for LOADONCALL code segments only, with DPMILD16 it applies to all segments. An exception are huge segments, which are always preloaded in DPMILD16. Segments with attributes PRELOAD and FIXED are loaded in conventional dos memory, unless OS type is OS/2. Segments with attribute DISCARDABLE are discarded if memory is low. DPMILD16 will load dlls only on first reference. Like Windows it uses a counter variable to count the references to a dll. If this count jumps from 0 to 1, the dll initialization code is executed. If the count jumps from 1 to 0, the dlls WEP procedure is executed if one exists and then the dll is unloaded. 3. Debugging Support DPMILD16 supports Int 41h in protected mode. That is, events such as loading a dll, starting a task, loading a segment a.s.o are all reported through calls to Int 41h with AX set appropriately. 4. API of the Loader þ Int 21h, AX=4B00h (LoadModule/LoadLibrary): Loads a NE module dynamically. Input: DS:DX - must hold a far16 pointer to the name of the module to load ES:BX - if an application is to be loaded, these must hold a far16 pointer to a execute parameter block. Output: AX - if a dll has been loaded returns the module handle (or 0 if an error occured) C - error Applications will execute synchronously, like in standard DOS, and your application will regain control when the loaded application has finished. For dlls, the module handle is returned in AX, which is simply the NE module header. The loader will not try to load applications having OS type 1 (Windows) or 6 (DPMI32) and route such calls to DOS. This will allow to launch 16-bit windows apps. Applications marked as OS/2 binaries will be loaded, however. þ Int 21h, AX=4B80h (FreeLibrary): Free a NE module. Input: DX - the handle of the module to free Output: AX - 0 indicates a failure þ Int 21h, AX=4B85h (GetProcAddress): Get address of a procedure in a module. Input: BX - holds the module handle CL - determines the type of the export and how DX is interpreted. If CL=1, DX is interpreted as a number. If CL=0, DX is interpreted as offset to a name. DS:DX - points to name of procedure if CL=0. Output: DX:AX - Address of procedure þ Int 21h, AX=4B86h (GetModuleFileName): Get a pointer to a module's full path and file name. Input: DX - holds module handle. Output: DX:AX - returns a far address to the module's path. C - error þ Int 21h, AX=4B88h (GetModuleHandle16): Get the handle of a NE module. Input: CL - determines the type of the module reference. If CL=0, DX is interpreted as an offset. If CL=1, DX is interpreted as a selector. DS:DX - must point to the name of the module if CL=0. Output: AX - the module handle. AX=0 indicates a failure. DX - holds the module handle of kernel þ Int 21h, AX=4B91h: enable/disable loader. This feature may be useful if another 16 bit DPMI clients is to be launched, but requires its own loader (Borland RTM.EXE). Input: BL - contains new state (1=enable, 0=disable). þ Int 21h, AX=4B93h (SetErrorMode): Set error mode flag SEM_NOOPENFILEERRORBOX. As default the loader displays error messages if it cannot load a module for some reason. Setting this flag will hide those messages. Input: EDX - new flags. þ Int 21h, AX=4B94h: Set new value of variable DPMILDR. Input: CX - mask for the bits to change DX - new values for these bits Output: AX - returns old value of the bits. Besides that the loader exports a subset of KERNEL.DLL functions. 5. Environment variable DPMILDR By setting the environment variable DPMILDR you can control some aspects of the loader's behaviour. The variable is a number whose individual bits are interpreted as follows: - bit 0 (DPMILDR=1): tell the debugger to stop at program entry point. The debugger is notified by an int 41h with AX=0040h and CX:BX=CS:IP. If no debugger is present, this switch has no effect. - bit 1 (DPMILDR=2): prevents the loader from moving itself into extended memory. It remains in conventional DOS memory after switching to protected mode. - bit 3 (DPMILDR=8): disables loader and tries to disable DPMI server if current app launches another application in NE format. This will result in new instances of loader and server to be initialized, so the launched app will have its own address space. Whether this option works as expected depends on the DPMI server. With HDPMI this option works fine. - bit 6 (DPMILDR=64): ignore SEM_NOOPENFILEERRORBOX flag. With this setting the loader will display errors during module loads in any case. - bit 8 (DPMILDR=256): try to load NE debug dll DEBUGOUT.DLL at startup. This is mainly for compatibility with older versions, where the loader has tried to load this dll unconditionally. 6. Returncodes Normally DPMILD16 returns the returncode of the (last) program it has executed. But there are several internal error conditions, which are reported to the caller through the following return codes: rc comment possible reasons ----------------------------------------------------------------- FB loader init error cannot switch CPU in protected mode DOS translation services not available memory shrink error (in real mode) no selectors available no extended memory available no conventional memory available FC client init error no filename supplied file not found no selectors available no extended memory available no conventional memory available FD error in exception 0Bh no more memory error in NE exe file FE application init error imports couldn't be resolved dll init returns with ax/eax=0 FF fatalexit application has called FatalExit or FatalAppExit DPMILD16 always displays an error text to STDERR in these cases. 7. History Since DPMILD16 and DPMILD32 share the same code base and many changes affect DPMILD32 only, there exist versions of DPMILD16 without any functional difference compared to the previous version. 05.09.2006: version 3.1.6 þ GetMuduleFileName may have caused a GPF if an invalid hModule parameter was given. þ bugfix: GlobalFree modified ES. This should only happen if ES contains the selector of the block which was released (then ES should be set to 0) þ in GlobalRealloc interrupts were disabled by "pushf cli" and restored by testing the pushed flags. Now DPMI functions 0900h and 0901h are used. 15.07.2006: version 3.1.5 þ switch DPMILDR=8 no longer tries to "hide" the DPMI host. þ if DPMILDR=8 is set, the loader will no longer create a child PSP for the application to launch (since there will be just one application). þ int 2F, ax=168Eh (to set the console title in win9x) is now only called if system *is* win9x. 14.06.2006: version 3.1.4 15.05.2006: version 3.1.3 02.05.2006: version 3.1.2 30.03.2006: version 3.1.1 27.02.2006: version 3.1.0 05.02.2006: version 3.0.9 þ error "invalid module handle" no longer displayed if flag SEM_NOOPENFILEBOX is set. 20.12.2005: version 3.0.8 06.12.2005: version 3.0.7 þ DPMILD16 displays to stderr now. 24.11.2005: version 3.0.6 18.11.2005: version 3.0.5 01.11.2005: version 3.0.4 21.10.2005: version 3.0.3 28.09.2005: version 3.0.2 19.09.2005: version 3.0.1 05.09.2005: version 3.0.0 þ bugfix: launching a real-mode app may have failed just because MZ-Hdr contained a "big" value at offset 3Ch. þ bugfix: if an image contained no preloaded segments, it may have caused a crash if it wasn't loaded as the first app. 28.08.2005: version 2.9.9 þ int 21h, ax=4B86h and ax=4B88h implemented þ bugfix: GetModuleFilename didn't work with a HINSTANCE þ check for SS == codesegment extended to DPMILD16. This allows the tiny model (code and data in one group) with DPMILD16 as well. 14.08.2005: version 2.9.8 06.08.2005: version 2.9.7 01.08.2005: version 2.9.6 20.07.2005: version 2.9.5 15.07.2005: version 2.9.4 13.07.2005: version 2.9.3 þ if OS type = OS/2, hold env selector in AX on startup. 06.07.2005: version 2.9.2 þ bugfix: DPMILD16 will now refuse to load a NE app marked as Windows app. This check was implemented long ago, but somehow had disappeared. Now implemented again. þ bugfix: DPMILD16 will now refuse to load a NE app marked as 32bit. These are special HX modules loadable by DPMILD32 only. þ module count now updated earlier, so on task entry it should have the correct value already þ if binary type is OS/2, InitTask is called internally before control will be given to the application. This allows OS/2 16bit apps to be run with DPMILD16 (if emulation dlls DOSCALLS/VIOCALLS/KBDCALLS exist). 27.06.2005: version 2.9.1 þ bugfix: load error in segment not present exception caused a fatal loader error (loader terminates) þ directory of .EXE added to dll search order (1. place) 23.06.2005: version 2.9 þ bugfix: export LoadModule crashed on return þ bugfix: _AHINRC/_AHSHIFT weren't exported with DM linker 8. Copyright DPMILD16.EXE is part of HX DOS extender. This extender is freeware. View HXRT.TXT for licence details.