[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[MiNT] Fwd: FPU emulation



I got this interesting mail today, perhaps it will inspire someone
to adapt this to MiNT :-)

/*
** Jo Even Skarstein    http://www.stud.ntnu.no/~josk/
**
**    beer - maria mckee - atari falcon - babylon 5
*/
---------- Forwarded message -----------
From: Henk Robbers <H.Robbers@cable.A2000.nl>
To: draco@mi.com.pl, joska@nuts.edu

Good day gentlemen.

I was tipped by "Stichting ST" that there are some questions floating around
on the floating point stuff.

Because I wrote an emulator for the 68000 with memory mapped FPU,
I have taken the freedom to send you some considerations of mine.
Consider this sort of a story.

On TOS's I know (2.06 & 3.06) the linef vector at absolute address 44,
or VBR displacement 44, is filled with a pointer to the "illegal instruction"
routine in ROM.

    If the CPU is 68000 that's all; no further action is needed. Even if a memory
mapped coprocessor is connected, the linef vector is not the correct entry
to this kind of FPU connection. The TOS's that implement a cookie jar
(I really dont know exactly which ones, > 1.4 ?) go looking for a IO FPU
by addressing $FA40 in combination with a temporary pointer in the BUS
error vector. If $FA40 is not a bus error, than the FPU is there and the cookie
is filled with the following values: _FPU   $00010000 .
This is how you recognise a SFP004 or WEIDE elektronic equivalent.
The linef vector keeps pointing at "illegal instr".

    If your TOS doesnt know a cookie jar then you must do
these things yourself. And that's exactly how Pure C does it, but only if
you compile for the software options (switch -8 off); it is the software
fp library that performs this check at runtime.
If you compile with switch -8 on, code is genereated for the
linef instruction set; no checkes are made because they probably are not even desired. With -8 on you  must link the appopriate
library (pc881lib).
(This lib contains mostly linef modules for scanf & printf :-)

I have found out that the pc881lib does not use any 68020+ features,
which made the whole enterprise worthwhile. This also lifted my
appreciation for the PureC boys.

When the CPU is 68020 or higher, Tos goes searching for a coprocessor
by putting a temporary vector in the linef vector and by issuing
a fmove fp0,d0 instruction.
Now if a coprocessor is present, this instruction is nicely executed.
In the other case the temporary linef routine registers the non presence.
If a true coprocessor is found the cookie jar is filled with _FPU $0002000,
which means either a 68881 or 68882 is present as true coprocessor.
After this, the linef vector is put back to illegal instruction, which in fact
is now completely dummy for the true coprecessor, cause nothing can
arrive there (or it must be by jumping or otherwise going astray).
In both cases (IO or true), arriving there is indeed illegal.

What to do if you write a emulator?  ;-)
First of all of course, fill the linef vector with a pointer to the emulator's
dispatcher.
The emulator I wrote (which you can find at  Stichting ST - de Thuishaven van Atari in Nederland  FPCPemu.prg  together with
sources) then keeps it simple,
it does not change the _FPU cookie, but adds a new cookie FPCP $00000001.
The reasons for this are the following:

    The $FA40 area is still valid and available for above mentioned
software fp programs that checks the IO FPU. Similar programs may also
use for instance the _CPU cookie together withe the _FPU cookie to decide
what to do. These will keep running as expected.
    Programs that are specially compiled to use the true coprocessor interface,
i.e. the linef set of instructions, need none of these checks, because they have
no choice ;-)  This is independent of whether the emulation is done with help
of the coprocessor, or in complete software.
They simply go bust if they're started on the wrong computer, which is rude,
but defendable (have yourself a solidly protected OS :~o).

When you download the emulator, you will notice that the instructions 'fsave'
and 'frestore' are not implemented. These are privileged instructions
for use in interrupt handlers in multitasking environments to preserve
the internal state of the FPU per process.
The TOS's which my coprocessor is designed for, do not issue these instructions (they even dont know them).
Application programs should well keep their hands of those.

For use in multitasking OS's these instruction have to be implemented.
Probably these instructions must be issued while interrupts are
inhibited.
My emulator does not inhibit interrupts while communicating
with the coprocessor and ignores "exception response primitives".
Also the code is not reentrant. Making it reentrant is not too difficult.
The emulator may become somewhat slower.
The few programs in which I use it work satisfactorily on my
1040ST with TOS 2.06.

I was able to get the thing working by carefully follow the instructions
in the following book: "MC68881/MC68882 Floating-point Coprocessor
User's Manual" chapter 7.  isbn  0-13-566936-7.

So, this emulator is not directly suitable for a multitasking environment,
but can function as an exemple of a working protocol.

The following may be of interest, (I posted this on 31 jan to comp.sys.atari.st):
The 68k linux team is working on a emulator for linux (multitasking!!).
Such an emulator should be able to work on any multitasking OS.

Motorola has on is site the following stuff:
 M68040FPSP Code (Tar & Packed)
which is a huge file I didnt succeed to download yet.

There is, but I am not sure (no documention found), another exception
vector, probably for use with the full 68040.
I call it "non_impl_f". It is at VBR displacement 52.
The fpu emulator with the MILAN should set this vector
to do the linef instruction that are not implemented in the full 68040.
These are mainly the more complex processes such as cos, sin etc.
This vector is trapped by the coprocessor itself in response to a otherwise
valid line_f command to those not implemented instructions.
Emulating these non_impl_f 's you can use all implemented line_f commands
as normal.

Motorola says: "The 040 is so fast, we couldnt implement it on chip faster
at the moment".  But that must have been quite a few years ago ;~)

While hoping this information to be usefull, I will be sincerely yours.

Henk Robbers.