[comp.os.msdos.programmer] Protected mode/Real mode switching

mackay@eecae.ee.msu.edu (James F. MacKay) (04/15/91)

Can someone explain to me how to write a program that is capable
of running normally in protected mode, but can switch into real
mode for DOS calls?  MS C and/or ASM preferred.

Thank You!

valley@gsbsun.uchicago.edu (Doug Dougherty) (04/16/91)

mackay@eecae.ee.msu.edu (James F. MacKay) writes:

>Can someone explain to me how to write a program that is capable
>of running normally in protected mode, but can switch into real
>mode for DOS calls?  MS C and/or ASM preferred.

Get DJ Delorie's MS/DOS port of GCC.
--

	(Another fine mess brought to you by valley@gsbsun.uchicago.edu)

dj@ctron.com (DJ Delorie) (04/16/91)

In article <1991Apr15.160333.8107@msuinfo.cl.msu.edu>, mackay@eecae.ee.msu.edu (James F. MacKay) writes:
> Can someone explain to me how to write a program that is capable
> of running normally in protected mode, but can switch into real
> mode for DOS calls?  MS C and/or ASM preferred.

First, get Intel's programmers reference/guide/etc for the appropriate
processor.  Last I recall, there's an intro, guide, reference, and
system software guide.

Second, guess heavily.  This doesn't seem to be a popular subject at
your local bookstore.

Switching back to real mode is a big problem on 286's, as the chip
can't do it by itself.  386's have an instruction for it.

VVVV This part of the response is for 80386 protected mode only VVVV

If you can learn by example, and have FTP available, download my gcc
port from grape.ecs.clarkson.edu via anonymous FTP to pub/msdos/djgcc.
The sources for the 386 extender (go32) are included.  It should be
posted to comp.binaries.ibm.pc when it gets to the head of the queue.


DJ
dj@ctron.com

dcc@hpopd.pwd.hp.com (Daniel Creswell) (04/17/91)

Which chip are you using 386 or 286? If it's a 386 then there's an instruction
to do it. However as you're asking this question I think you're on about the
286.

Now the bad news. The only way to switch back to real mode is to use the reset
op. i.e. Just like you'd powered off and on. I dunno how it's done technically
but I imagine you wedge a vector and once reset is achieved your code gets
control back. At this point now doubt you'd wanna restore register's etc.

Hope thats some help - I guess a Microsoft programmer on the Windows team'd be
perfect for this question.

Cheers,
	Dan.

sdawalt@valhalla.wright.edu (Shane Dawalt) (04/21/91)

From article <1991Apr15.160333.8107@msuinfo.cl.msu.edu>, by mackay@eecae.ee.msu.edu (James F. MacKay):
> Can someone explain to me how to write a program that is capable
> of running normally in protected mode, but can switch into real
> mode for DOS calls?  MS C and/or ASM preferred.
> 
  Switching from protected to real mode in 286 processors is not
trivial, but is possible.  I recomment obtaining the latest
INTER???.ZIP from SIMTEL20 at PD1:<MSDOS.INFO>.  This document shows
the location of the "reset code" in the BIOS and the useful code
values.  This code is checked by the BIOS each time the system is
booted (reset or powerup).  If this word is set to 1234H then the
POST stuff is not executed and control is given directly to DOS.
This is important for 286 protected to real mode switching since the
only way to kick the 286 out of protected mode it to reset it.
This, of course, requires resetting the entire machine.  Using
this special code, you can somewhat quickly set the 286 to real
mode.

  Shane();

--------------------------------------------------------------------------
From the keyboard of:			     email: sdawalt@cs.wright.edu
	Shane A. Dawalt
--------------------------------------------------------------------------

steves@hpuamsa.neth.hp.com (Steve South CRC) (04/23/91)

I was just looking through the HP Vectra 286/386 BIOS Technical Reference
manual (HP Part No. 5959-7745) which does give *some* information about this.
There is nothing plastered over the manual to suggest it is HP confidential
so I guess yu could get a copy. I don't know how generic the information is
though.

To summarise the manual, as the previous reponses indicated, the only way to
get from protected mode to real mode is to do a processor reset. From software
this may be done by getting the 8042 keyboard controller to toggle the 80286
reset line, or by doing a jump to FFFFFFF0h. The question now arises for the 
BIOS "is this a power up, or is it a return from protected mode?"

On the Vectra the BIOS looks at CMOS addres 0Fh, which is the shutdown status
byte. I don't know whether this value is set by the BIOS when protected mode
is entered, or if you must do it yourself. I would *guess* the former.

As far as entering protected mode is concerned, you need INT15h with AH=89h.
From here on it gets beyond my knowledge of 80286. One point though. The
aforementioned manual says that address line A20 must be released prior to
entering protected mode, and it is your program's responsibility to do this
by issuing the approriate command to the 8042 keyboard controller.

I wish you the best of luck.....                    

Steve South.
HP Analytical Response Centre.
Amstelveen, Netherlands.

----------------------------------------------------------------------------
#include <standard.disclaimers>
----------------------------------------------------------------------------

orenalex@bimacs.BITNET (oren alex) (04/24/91)

In article <37390009@hpopd.pwd.hp.com> dcc@hpopd.pwd.hp.com (Daniel Creswell) writes:

>Now the bad news. The only way to switch back to real mode is to use the reset
>op. i.e. Just like you'd powered off and on. I dunno how it's done technically
>but I imagine you wedge a vector and once reset is achieved your code gets
>control back. At this point now doubt you'd wanna restore register's etc.
>
>Hope thats some help - I guess a Microsoft programmer on the Windows team'd be
>perfect for this question.

Wasn't there an undocumented "load all" function?
Could it help?

dj@ctron.com (DJ Delorie) (04/25/91)

In article <3199@bimacs.BITNET>, orenalex@bimacs.BITNET (oren alex) writes:
> In article <37390009@hpopd.pwd.hp.com> dcc@hpopd.pwd.hp.com (Daniel Creswell)
> writes:
> >Hope thats some help - I guess a Microsoft programmer on the Windows team'd
> >be perfect for this question.
> 
> Wasn't there an undocumented "load all" function?
> Could it help?

There is such an opcode, and Microsoft used it in OS/2 for 286
machines.  From what they told me, they had a really hard time getting
Intel to tell *them* about it.  They used it primarily to set up the
hidden portion of the segment registers in real mode to access memory
above 1M.  It is *not* available on the 386, and may not exist on new
286 designs, or on non-Intel 286's.  It's very non-portable, also.

DJ
dj@ctron.com

valley@gsbsun.uchicago.edu (Doug Dougherty) (04/26/91)

dj@ctron.com (DJ Delorie) writes about the 286 LOADALL instruction:

>There is such an opcode, and Microsoft used it in OS/2 for 286
>machines.  From what they told me, they had a really hard time getting
>Intel to tell *them* about it.  They used it primarily to set up the
>hidden portion of the segment registers in real mode to access memory
>above 1M.  It is *not* available on the 386, and may not exist on new
>286 designs, or on non-Intel 286's.  It's very non-portable, also.

I've heard others claim that there is no 386 LOADALL as well.
However, I have a document (available upon request) that purports to
describe the 386 version of LOADALL; apparently it is only partially a
superset of the 286 version.
		-----------------------------------------
Certainly the use of LOADALL is akin to usage of the undocumented
features of the AAD & AAM instructions; "Undocumented DOS" has a very
good section on the distinction between using undocumented features of
the OS (which they argue is inescapable) and using undocumented features
of the chip (which they claim is inexcusable).  However, I think if MS
uses it (LOADALL) in their systems (an operating system, no less) that that
pretty much legitimizes it.  Can you imagine some clone 286 manufacturer
having to admit that their chips won't run OS/2?
--

	(Another fine mess brought to you by valley@gsbsun.uchicago.edu)

dj@ctron.com (DJ Delorie) (04/27/91)

In article <1991Apr26.160753.4754@midway.uchicago.edu>, valley@gsbsun.uchicago.edu (Doug Dougherty) writes:
> Certainly the use of LOADALL is akin to usage of the undocumented
> features of the AAD & AAM instructions; "Undocumented DOS" has a very...

As an aside, I have a book by the designer of the 8088/8086 that
documents the "extra" features of the AAD and AAM instructions, so
they're not undocumented.

Also, the fact that the 386 can transition from protected mode to real
mode without a reset means that you can set the segment registers to
arbitrary memory ranges with the MOV ES,AX instruction and a properly
set up GDT.  The OS/2 version that I referred to that used the LOADALL
instruction was 1.0, and I hope they have "fixed" it since then.  They
claimed that there was no 386 version as well.

DJ
dj@ctron.com

goldstein@arecibo.aero.org (Fogbound Child) (04/27/91)

-Message-Text-Follows-
In article <1991Apr26.160753.4754@midway.uchicago.edu>, valley@gsbsun.uchicago.edu (Doug Dougherty) writes...
>dj@ctron.com (DJ Delorie) writes about the 286 LOADALL instruction:
> 
>>There is such an opcode, and Microsoft used it in OS/2 for 286
>>machines.  From what they told me, they had a really hard time getting
>>Intel to tell *them* about it.  They used it primarily to set up the
>>hidden portion of the segment registers in real mode to access memory
>>above 1M.  It is *not* available on the 386, and may not exist on new
>>286 designs, or on non-Intel 286's.  It's very non-portable, also.
..
>uses it (LOADALL) in their systems (an operating system, no less) that that
>pretty much legitimizes it.  Can you imagine some clone 286 manufacturer
>having to admit that their chips won't run OS/2?

My new '486 motherboard has a set of options in the CMOS chipset 
configuration regarding exactly that. You can reconfigure the chipset to 
honor the LOADALL memory access if you want to run OS/2, or you can disable 
that feature (and gain about 1k of main memory, I think).

It's hard to imagine that some undocumented feature can evolve into 
something so significant that chipset manufacturers are changing their 
PALs...

>--
> 
>	(Another fine mess brought to you by valley@gsbsun.uchicago.edu)

___Samuel___
_________I_claim_and_accept_sole_responsibility_for_the_above._SjG.____________
<goldstein@aerospace.aero.org| "Real Mode is required primarily to setup the
  There's no need to cure a  |  processor for Protected Mode operation."
   C8-H10-N4-O2 addiction.   |	80386 Hardware Ref. Man., p. 4-174, Intel.

rcollins@altos86.Altos.COM (Robert Collins) (04/30/91)

In article <1448@balrog.ctron.com> dj@ctron.com writes:
>> Wasn't there an undocumented "load all" function?
>> Could it help?
>
>There is such an opcode, and Microsoft used it in OS/2 for 286
>machines.  From what they told me, they had a really hard time getting
>Intel to tell *them* about it.  They used it primarily to set up the
>hidden portion of the segment registers in real mode to access memory
>above 1M.  It is *not* available on the 386, and may not exist on new
>286 designs, or on non-Intel 286's.  It's very non-portable, also.
>

LOADALL is available on both the '286 and '386.  However, it is
implemented as different op codes on each processor.  '286 LOADALL
is op code 0F 05, and '386 LOADALL is op code 0F 07.  In the October
issue of 'TECH SPECIALIST' is an article I wrote discussing LOADALL 
for both the '286 and '386.  Included in the article is a detailed
description of the instruction, and source code examples showing how
to use it on each processor.  Also included is a LOADALL emulation
TSR written for the '386.  This routine will use '386 LOADALL to
emulate '286 LOADALL.

The '486 has LOADALL, but is not accessible via an op code.



-- 
"Worship the Lord your God, and serve him only."  Mat. 4:10
Robert Collins                 UUCP:  ...!sun!altos86!rcollins
HOME:  (408) 225-8002
WORK:  (408) 432-6200 x4356

valley@gsbsun.uchicago.edu (Doug Dougherty) (05/01/91)

rcollins@altos86.Altos.COM (Robert Collins) writes:

>LOADALL is available on both the '286 and '386.  However, it is
>implemented as different op codes on each processor.  '286 LOADALL
>is op code 0F 05, and '386 LOADALL is op code 0F 07.  In the October
>issue of 'TECH SPECIALIST' is an article I wrote discussing LOADALL 
>for both the '286 and '386.  Included in the article is a detailed
>description of the instruction, and source code examples showing how
>to use it on each processor.  Also included is a LOADALL emulation
>TSR written for the '386.  This routine will use '386 LOADALL to
>emulate '286 LOADALL.

>The '486 has LOADALL, but is not accessible via an op code.

Then how, pray tell (given your .signature, this cliche seems appropriate)
is it accessed?  Magic?  (IN/OUT ?)
--

	(Another fine mess brought to you by valley@gsbsun.uchicago.edu)