On Tue, 29 Aug 2017 16:27:02 +0700
JJ <
jj4p...@vfemail.net> wrote:
> My aim here, is to have a multi platform executable file so that the
> program can be at its best in each platform / system mode. [Sigh],
> I'm not just trying to make sure that my program can work on both DOS
> and Windows.
Ok. I can't really help further with a multiple operating system
executable type as I'm not familiar with the format of most
executables, except for DOS DPMI's and DOS .com's.
FYI, 32-bit DPMI is a good choice though, as long as you're not running
a recent version of Windows, such as Win 10, and also not running Linux
or a MacIntosh. 32-bit DPMI apps work with the many versions of DOS
and most versions of Windows in a console window. I'd guess that this
is the most widely supported executable type.
FYI, the way I got into development of my own operating system was
because I was wanting an "universal" DPMI host that worked with both
DJGPP and OpenWatcom.
Personally, I'd think it best to define the following as note all code
will execute with all operating systems.
1) which operating system environments you'd like to execute your code
2) which compilers will generate the code and what type of code
3) compare with which types of code the operating system can execute
Also, I'm not sure this is the best group. I'm not sure that there is
a perfect group either, but those on comp.lang.asm.x86 and
alt.os.development has discussed similar issues in the past. One is
for x86 assembly and the other is for operating system development.
A couple hobbyist compiler developers hang around on a.o.d. who've
produced compilers which generate binaries for multiple targets.
I.e., they may be familiar with the executable formats you're using.
The issue of portable code, generally high-level, not binary
executables, has come up on comp.lang.misc from time to time.
> I'm aware that there may be compabitility issues when using DPMI, but
> I didn't know it could be that severe.
>
> In case of an incompatible DPMI host, I was thinking of detecting
> whether the incompatible DPMI host is present or not, before actually
> starting to go into protected mode.
You should be able to detect PM by using the SMSW instruction, since
MOV CR0 is privileged and will GP fault, if not executing code in ring
zero. IIRC, you may need an operand size override on SMSW.
http://qcd.phys.cmu.edu/QCDcluster/intel/vtune/reference/vc296.htm
DPMI v0.9 lists INT 0x2F, AX=1686h "Get CPU Mode" as bimodal. It must
work for both RM and the PM (either 16-bit or 32-bit) of the DPMI host,
if the DPMI host is present. It should not be called unless DPMI is
available. So, if DPMI is present, you can call this to determine the
processor mode of the code, i.e., in RM w/DPMI host loaded but no PM
code is executing, or in PM w/DPMI host loaded and PM code is executing.
As for detecting the DPMI host itself, calling INT 0x2F, AX=1687h
"Obtain Real-to-Protected Mode Switch Entry Point" should be
sufficient. This is a RM interrupt function. This tests for the
presence of DPMI *AND* provides an address for RM to PM entry. I.e.,
if this fails, no DPMI host is loaded. Of course, if you're using
compiled code, you need to know what mode you're code is in to determine
your languages' appropriate call-interrupt routine. High-level
languages usually have at least two routines, one for making RM
interrupt calls from RM code, and one for making RM interrupt calls from
PM code. You should know this from the commands you use to produce
the executable, e.g., 16-bit RM or 32-bit DPMI.
Also see SMSW above to determine PM or RM.
Also note that some DPMI hosts are 16-bit PM, not 32-bit. Most of the
DPMI hosts for high-level languages are 32-bit PM. INT 2Fh, AX=1687h
will also tell you whether the DPMI host is 16-bit PM or 32-bit PM.
> I don't know if I can enter protected mode
> manually via high level programming language such as C or Pascal.
The compiler should link in the code that sets the appropriate
processor mode for the code if required, i.e., 16-bit RM (nothing),
16-bit PM w/DPMI (DPMI stub), 32-bit PM w/DPMI (DPMI stub). So, you
shouldn't need to enter PM unless your compiler produces 16-bit RM code.
If 16-bit RM code, yes, you'll probably have to code some assembly to
effect the RM to PM switch, if you're not using a DPMI host (call INT
0x2F, AX=1687h) and not executing under an OS like Windows or Linux
which use PM. Without a DPMI host and not executing under Windows or
Linux, a PM environment implementation is entirely up to you. Of
course, you can't switch into PM while executing under a PM OS like
Windows or Linux as they are PM operating systems. Of course, most
versions of Windows except Win 10, offer a console window for 16-bit RM
v86 mode code that can call Windows 32-bit DPMI and execute 32-bit code.
There is also a BIOS call that switches into PM from RM, but I don't
know if it's reliable. See:
INT 15h, AH=89h "Switch to Protected Mode"
http://www.delorie.com/djgpp/doc/rbinter/ix/15/89.html
INT 15h, AH=87h "Copy Extended Memory"
http://www.delorie.com/djgpp/doc/rbinter/id/35/15.html
> The only way I could think of is to use a separate, pure DOS only
> program which detect the presence of any incompatible DPMI host,
> before actually running the main program's executable file.
If you are executing from DOS or a Windows console, your code starts as
16-bit RM code, for DOS as either in RM or v86 (modified 16-bit RM under
PM control), or for Windows console as v86 mode.
From RM or v86 mode, your codes' DPMI stub will, or your code can, call
INT 2FH, AX=1687H to detect DPMI. If your code is PM, you should know
that, but you can call this function from PM code too. From PM, you'll
need to know you're in PM, i.e., 32-bit DPMI code, so you know which
library call to use. The appropriate interrupt function will switch
from PM to RM to call RM interrupts, and return to PM.