[comp.os.msdos.programmer] Teaching and Old Dog New Tricks

jwbirdsa@amc-gw.amc.com (James Birdsall) (12/18/90)

In article <1990Dec16.071745.19811@NCoast.ORG> ramsey@NCoast.ORG (Cedric Ramsey) writes:
>I am curious as to why DOS can't exceed the 640K barrior.

   As other posters have pointed out, it can. The problem is that the
upper 384K are reserved for other hardware. Depending on what additional
hardware is installed, it is sometimes possible to add more.

>Why not just rewrite DOS for a 32bit address space.

   The problem here is that DOS runs in what is called "real mode." Any
80x86 running in real mode is essentially reduced to being a fast
8086/88 with a few more instructions. The additional address lines are not 
available.
   In order to access the additional address lines (and hence the full
memory space), the chip must run in "protected mode." Protected mode is an
improvement over real mode in a variety of ways. In particular, it includes
hardware provisions for memory protection, virtual memory, etc.
   So what's the problem? DOS and DOS programs are written assuming a
certain arithmetic relationship between segments and offsets, namely that
an offset can be converted to a segment by shifting right four bits, and
that the "flat" 20-bit address is calculated as: the segment shifted left
four bits (in a 20-bit space so as not to lose the high four digits) and
then added to the offset. Thus, 0000:0402 is equal to 0040:0002. And 
0020:0202. And 0010:0302.
   This breaks down in protected mode, where the segment value is a handle
into a table of segment descriptors. Hence, most DOS executables will not
run in protected mode. Nor DOS itself, nor the BIOS in ROM that DOS relies
on. While there are presumably other problems, this one by itself is enough
to kill rewriting DOS very dead. It could be done, but why? None of the
programs would run, which would be the only point of doing it in the first
place. There are already plenty of more advanced *in*compatible OSes.

   Why were programs written this way? Well, the easy answer is: large
data objects. Multiple segments are not the problem. The handle is still a
16-bit value (to fit into the segment register) and far pointers would work
just as well with a handle in the segment word as with an actual segment.
The problem is single data objects larger than a segment. The easiest way
to access a large array is to fool around with the segment value as well as
the offset. If done "properly", the array would wind up in two or more
segments and the compiler (and executable) would have to go through strange
contortions to access an element, generate a pointer to that element, or,
even worse, do pointer arithmetic between two elements in the array.
Indeed, if the two elements are in different segments, the result is not
well-defined. Thus, in the interests of speed, simplicity, and sanity,
segment arithmetic was born and DOS was stuck in real mode forever.

-- 
James W. Birdsall      | amc-gw!jwbirdsa@uunet.uu.net | For it is the doom of
=======================| 71261.1731@compuserve.com    | men that they forget.
jwbirdsa@amc.com       | CompuServe: 71261,1731       |    --Merlin
uunet!amc-gw!jwbirdsa  | GEnie: J.BIRDSALL2           |======================

jamesp@world.std.com (james M peterson) (12/18/90)

><1990Dec16.071745.19811@NCoast.ORG> ramsey@NCoast.ORG (Cedric Ramsey) writes:
>>
>>If anybody can explain why DOS can't be enhanced, in a compatible way, 
>>without the excuse 'it was written for the 8088', 
>While on a similar subject, why does IBM say DOS can't be used for any
>multitasking, yet, there were some "hidden" and "undocumented" interrupts,
>
>Robert Douglas Davis     # Is reality real?  Can you prove it? 
>cs202101@umbc5.umbc.edu  # Can you write an algorythm to prove it?

Some light (but expensive) reading of note:  In the ms-dos encyclopedia
there is some talk about the directions microsoft wanted to push dos vs.
the directions its big mother wanted it to go.

It seems that microsoft wanted to put in multi-tasking in 3.1 (??) but 
ibm wanted network support first - guess who won?  It would make sense
to have m-tasking first so that a network process could be loaded and run.

All from memory - dos versions may vary..

jamesp@world.std.com         'Reality is not an industry standard'

valley@uchicago (Doug Dougherty) (12/20/90)

hughes@maelstrom.Berkeley.EDU (Eric Hughes) writes:


>In article <4550@amc-gw.amc.com> jwbirdsa@amc-gw.amc.com (James
>Birdsall) writes:
>   [about segment arithmetic]
>>Why were programs written this way? Well, the easy answer is: large
>>data objects. 

>Not only that.  The old Lattice C compiler, when using large model,
>used to normalize every pointer so that the offset was between
>one and sixteen.  They did this to facilitate pointer comparisons,
>from what I could tell.

>What numbskulls.

>Eric Hughes
>hughes@ocf.berkeley.edu

You mean between 0 & 15  (0 & 0F).

In TC, these are called huge pointers and you only get them (even if you
compile in the huge model (!)) if you explicitly request them (via the
"huge" modifier in the pointer definition)

This scheme is logical, but it caught me when I assumed that compiling
in the huge model would automatically get me huge pointers...

stanley@phoenix.com (John Stanley) (12/20/90)

valley@uchicago (Doug Dougherty) writes:

> You mean between 0 & 15  (0 & 0F).

   Between -1 and 16. Or, in the range 0 to 15, inclusive.

   The rock is not _between_ the rock and the hard place.

bcw@rti.rti.org (Bruce Wright) (12/30/90)

In article <826@fnx.UUCP>, del@fnx.UUCP (Dag Erik Lindberg) writes:
> ---------
> Different answer here: Why the 640k address space?  I've seen people
> beat around the bush on this one, but here is the bottom line.  The
> question was: Why can't 286 and greater computers have a bigger address
> space and have upward compatibility with old MSDOS?
> 
> The answer is:  Because the video screen, BIOS, and disk controller (etc)
> are smack dab in the middle of the address space if you try to extend past
> approximately 700k.  MSDOS is not designed to deal with a non-linear
> address space, it could never live with a big hole there.  Imagine
> loading up 400k of TSR's and then trying to run a 400k program.  Where
> would you put it?  How would you tell the application that any code it
> wanted to execute after the first 240k is actually located out beyond
> the 1024k region?

The first part of this article was pretty good, but I think this is
not very accurate.

MS-DOS can certainly deal with more than 640K of memory (consider the
DEC Rainbow, which can have up to 896K of real memory), and I don't
see any reason it would have to be contiguous (though that would be
the most useful, since there is no page mapping to deal with
fragmentation - but you could always allocate several noncontiguous
segments just fine, it's just a bit of a pain).  MS-DOS actually
does have a memory allocation list, so it can deal with noncontiguous
segments (just not very effectively, if you aren't careful then memory
fragmentation may cause out-of-memory problems even if the total
amount of free memory is sufficient).

The real issue (if you'll pardon the pun :-) is that too many programs
are aware that they are running in a 20-bit address space, doing
segment arithmetic of one sort or another.  Therefore, they are not
able to run in an environment where the segment arithmetic doesn't
work they way that they expect.  Even if the programmer didn't
explicitly do segment arithmetic, many compilers or subroutine
libraries do, and that's all that's needed to keep it from working.

>  (In case you didn't know, with one megabyte of memory,
> the first 640k are mapped from 0-640k, then the remaining 384k start
> at 1024k, or 1Meg.  In between 640k and 1024k are all the BIOS and
> memory mapped I/O stuff of the PC compatibles.)

This is a common configuration, but it isn't the only one.  Some
clones use some of the upper 384K as a shadow RAM for the BIOS, or 
even put it up at the top of the address space (16M-384K on a 286)
instead of at 1024K.  (I think the latter is sort of silly, but
it does exist).

						Bruce C. Wright