[net.arch] 68000 "small model"

gnu@sun.uucp (John Gilmore) (06/28/85)

Steve Villee (asuvax!anasazi!steve) said:
> So it might well be that all code and data would have to fit in the
> first 32K.  In any case, this 68000 "small model" does not readily
> upgrade to something analogous to the Intel medium model (separate
> code and data, with 64K for each).
The easy way to do 68000 code addressing is to use position
independent code (jump/jsr pc-relative with 16-bit offset) which allows
32K minimum of code (or more depending on the pattern of jumps within
the code), no matter how you address your data.  Thus there is no
true "small model" but more like a "medium model" as the smallest.
The code can go anywhere in memory.  (See below about the data.)

The real win is that while there is no *exact* correspondence to the
Intel "small" and "medium" models, the "large" model is not complicated
or hard to generate for on the 68000.  You can afford to push a program
from small to large model on the 68K because it really doesn't cost
that much.  That's not true on the 8086, and it's much worse on the 286
-- the compiler and the kernel need to agree how to assign segments to
be able to index large arrays!

In the 68000, the stack looks identical regardless of your "model", so
you can link a small model subroutine library with a large model
mainline, or vice verse.  (Intel really botched it there, though
Motorola has picked up the botch in their new CALLM/RETM instructions
in the 68020, which are kinda like VAX doitall subroutine calls.
They're incompatible on the stack with JSR, so you have to know which
kind of routine you're calling if you use it.  Result:  We don't use it.)

> A fairer "small model" for the 68000 would use (Am,Dn.W) addressing
> modes, with the 16-bit pointer in Dn and some kind of base address
> in Am.  This would provide closer to the same capability that Intel
> small model provides.  But of course this would be slower than the
> large model!
Not true; you picked the wrong addressing mode.  Select one or several
A-registers and call them "segment registers".  Now you can generate
code using the "Address reg with 16-bit constant offset" mode, which
runs the same speed as 16-bit absolute addresses, due to the 68000's
pipelining.  (It has already fetched the offset, and it can do the add
while it prefetches the next 16 bits to replace the offset.)  This
gives you a 64K addressing area based on a reloadable pointer (in a 24-
or 32-bit address space), which is very similar to the 8086 medium model
except that you have up to seven "segment" registers available.

richardt@orstcs.UUCP (richardt) (07/10/85)

While you're trying to simulate a segmented architecture, although
I can't see why anyone would want to, there is a very simple dodge:
designate one or more address registers as Data Register pointers,
and do the same for any other segments.  Then load the 'segment'
into the high word of the address register(s).  after doing this,
you can use indirect jumps (JMP.L (Ax)) to simulate a 64k code space,
after loading the offset into the low word of Ax;  you can address arrays
by loading the offset into the low word of the Data Segment Register (Ax)
and then use the standard array addressing modes, which is essentially
the same trick mentioned above;  and you can keep one Address register
as a dedicated segment register, and use array and offset modes to 
simulate the offset + segmant address.

Given that you can fake a segmented 68xxx, why bother?  It is usually
far easier to write relocatable code.  Unlike the Intel chips, its easy
with a 68xxx.  Another way of simulating a "small model" environment is
to program the MMU correctly.
						orstcs!richardt
"If I'm human, what are *YOU*?"