Operation of the INTeL 80386 is clearly much more flexible than currently
used, as far as the basic states the machine can run in. "Real Mode" and
"Protected Mode" are two possibilities out of several that are concievably
useful. It can be seen from things that are possible in "Real Mode", such
as "Unreal Mode", use of 386-era instructions and so on, that the
canonical modes are not monolithic entities, but are cases of various
combinations of discrete state switches. There is no 8086 in a 386.
Canonical Wake-up Real Mode, which I will refer to as CWR Mode, seems to
be how these several state switches are set at machine reset, but are
semantically just settings of independant things, and clearly CWR Mode can
be set up from individual settings available to the user. This is also
much more evident from a careful traversal of the detailed instruction
specs in the INTeL Programmer's Reference (386INTEL.TXT) for the 80386.
I'd say the two most global switches in the machine are the PE bit,
Protection Enabled, quite sensibly placed at bit 0 in control register 0,
and the D bit of the active code segment descriptor affiliated with CS,
the Default Bit. Two bits gives four possible states. All four are capable
of being the default mode of a system. Two are used as such; CWR Mode and
Protected Mode. Here's a breakdown and some neologizing...
PE=0 Dbit=0 (un)Real Mode
PE=0 Dbit=1 Forreal Mode
PE=1 Dbit=0 Veal Mode (BKA "286 task")
PE=1 Dbit=1 Protected Mode
The documented modes are the outside cases in a binary-count listing,
where PE=Dbit. There's a very good reason for that. IRET is sensitive to
Dbit, whereas interrupts push a stack frame of operands sized in
accordance with PE. This is some of INTeL's* description of the action of
INT, which represents all interrupts in this regard, when PE=0...
IF PE = 0
THEN GOTO REAL-ADDRESS-MODE;
REAL-ADDRESS-MODE:
Push (FLAGS);
IF <! 0; (* Clear interrupt flag *)
TF <! 0; (* Clear trap flag *)
Push(CS);
Push(IP);
(* No error codes are pushed *)
CS <! IDT[Interrupt number * 4].selector;
IP <! IDT[Interrupt number * 4].offset;
That is, IP is pushed if PE=0, not EIP. FLAGS is also a dual (a "word" in
INTeLese, 16 bits). Thus if, for example, you are in Forreal Mode, you get
a 6-byte stack push of FLAGS, CS and then IP on an interrupt, and the
corresponding IRET will later pop 12 bytes for basically the same 3
registers, and the system streaks off to the big bitbucket in the sky.
HOW ever, IRET is only PARTIALLY sensitive to Dbit. What I didn't say a
moment ago is that IRET is really sensitive to the current effective code
size, of which the D bit is just one component. If we prefix the IRET in a
Forreal Mode interrupt handler with 0x66, the other-operand-size prefix,
it will pop duals in a use32 CS. The interrupt occuring with PE=0 pushed
duals. It works. The inside cases of Veal Mode and Forreal Mode simply
need thier IRETs un-default-sized. In Veal Mode you coerce IRET into using
quads in a use16 code segment, and in Forreal Mode the same prefix in a
use32 code segment will coerce the IRET pops to duals. In Veal Mode, where
PE=1 when an interrupt occurs, you also have the option of handling the
interrupt with a Dbit=1 segment for the pertinent interrupt handler, in
which case it can IRET back to Veal Mode with a naked IRET. I suppose you
can also segregate Veal Mode segments with thier descriptor bases and
limits. In all the quirkiness of the 386, the broad orthogonality of the
other-sizing prefixes is quite refreshing, and even works on stuff like
POPA.
This is from the blow-by-blow description of IRET...
IF OperandSize = 32 (* Instruction = IRETD *)
THEN EIP <! Pop();
ELSE (* Instruction = IRET *)
IP <! Pop();
Again, OperandSize is Dbit as effected by a possible prefix.
This is why INTeL only mentions Veal Mode as "286 tasks". Tasks don't
IRET. Most of what a 386 provides big facilities for, like tasks, can also
be done piecemeal, as would be the case running a system in straight
Forreal Mode.
Canonical Wake-up Real Mode and Unreal Mode are two flavors of the same
basic setting of PE and Dbit. The difference is in segment limits. This
points up a basic concept here. 8086-style segments are a lightweight
layer that may or may not be active, but 386 segments are always active.
PE=0 does not turn them off. PE=0 means you can't change them until you
turn PE back to 1. PE should be called "PCE, Protections Changes Enabled".
This means the four basic modes have a state diagram about like so...
_______________
| WAKE-UP |
|canonical rmode|
| PE=0 use16 |
|_______________|
A |set PE to 1
| |
set PE to 0| |
___|________V__
| Veal |
| Mode |
| PE=1 use16 |
|_______________|
A |far xfer
| | to use32 CS
far xfer to | |
use16 CS| |
___|_______V___
| Protected |
| Mode |
| PE=1 use32 |
|_______________|
A |set PE to 1
| |
set PE to 0| |
___|________V__
| Forreal Mode |
| Mode |
| PE=0 use32 |
|_______________|
Interesting. Forreal Mode is the furthest from Wake-up, and you can only
get to Forreal Mode from pmode. Forreal Mode is like a back room off of
pmode. You can interrupt between pmode and Veal Mode. Conversely, events
in rmode or Forreal Mode (PE=0) have to be handled in the mode they occur
in.
The above diagram does not account for different segment limits and bases
than those in effect in WakeUp Rmode, so e.g. unreal mode is not shown.
This chart also does not account for V86 Mode, which basically requires
386 task-switch constructs. The above modes and transitions do NOT need a
TSS, or paging. I suspect V86 could run off Veal Mode OR pmode.
Veal Mode is a protected mode. That means it's a quick switch to good old
use32 Protected Mode. It may afford some better code density, and thus
speed. Forreal Mode is unprotected, which means interrupts are handled
somewhat faster, which benefits realtime services. Either can be
incorporated into a multi-mode system. Forreal Mode also doesn't seem to
have any analogy at all in current use, other than the INTeL "flat model",
which is a simplified pmode, but that similarity is rather superficial.
For the 386 to do what it does, and particularly to have pulled it off in
the mid-eighties, things have to be fairly simple. You can figure that
whatever the 386 does, it's implemented as simply as possible. The modes
of the machine are composites of simple switches, and various effects,
such as loaded descriptors, tend to persist until changed. This has always
been the case with e.g. 8086 segment registers. In the 386, however,
8086-style "segments" are not alternates of 386 segments, they are a
superficiality on top of them. With that in mind, the states one goes
through simply getting from real mode to pmode start to make more sense.
The following (osimplay) code demonstrates the superficiality of 8086
"schmegments" vis-a-vis 386 segments, even when PE=0...
<from flat pmode>
. global/flipPE # Welcome to Forreal Mode
# cell still 4
= 4 to A # 32-bit schmegmented addressing demo
= A to ES # proving we got PE = to 0.
= 9348539 to A
= A to @ $((0xb8a00))
ES
= A to @ $((0xb8a00))
That code causes two identical attribute-glyph pairs to appear on the VGA
text screen 32 charcells displaced from each other. That is the 4 in ES,
times 16 as per 8086, divided by two since each charcell is 2 bytes. Plus
a flat 32-bit address to put it on the screen. Forreal Mode thus does
32-bit 8086 schmegmented address computation. What is this type of
addressing useful for? Precious little. In Forreal mode you've got 32 bits
to start with. The point is you have the big flat segments left over from
pmode. The 8086 address-math does prove we're not in pmode any more,
however. Otherwise the ES prefix of 4 would have GPFed.
A demo of Forreal Mode is in
http://distro.ibiblio.org/pub/linux/distributions/clienux/interim/Forreal.tgz
in my osimplay assembler written in Bash.
--
Rick (Richard Allen) Hohensee Party of one
candidate, President of the United States of America
humb...@smart.net Maryland, USA
Ground troops out of Iraq Put the CIA under INS
Semi-legalize drugs Prosecute Bush Tighten the borders
Isolate Israel Tax churches halve military aquisitions
platform http://www.smart.net/~humbubba/platform
Hohensee-Feingold Amendment http://www.smart.net/~humbubba
Do I understand correctly that the "Veal" mode pertains to naive calves
taken from their moms at an early age, and raised entirely in the dark? ;-)
--
Julian V. Noble
Professor Emeritus of Physics
http://galileo.phys.virginia.edu/~jvn/
"As democracy is perfected, the office of president represents, more and
more closely, the inner soul of the people. On some great and glorious
day the plain folks of the land will reach their heart's desire at last
and the White House will be adorned by a downright moron."
--- H. L. Mencken (1880 - 1956)
It's about a strange juvenile state. It doesn't really have to be bovine.
>
>--
>Julian V. Noble
>Professor Emeritus of Physics
>
>http://galileo.phys.virginia.edu/~jvn/
>
> "As democracy is perfected, the office of president represents, more and
> more closely, the inner soul of the people. On some great and glorious
> day the plain folks of the land will reach their heart's desire at last
> and the White House will be adorned by a downright moron."
>
> --- H. L. Mencken (1880 - 1956)
Nice quote.