- Floating point package which implements (in single precision) the
basic algebra and the standard functions. The floating point number
format is the 32-bit IEEE format. This package is not utilized
in 68020/030 systems with 68881/882 or 68040. On 68040 systems, the
emulation of transcendental functions etc. is left to a supervisor-state
exception handler which is not part of RTF.
- Input/output to the host computer's file system, independent of the
kind of hardware link between host and microprocessor. OPEN and subsequent
WRITE e.g. to a magnetic tape connected to the host is possible. A small
support program (which is contained in the RTF/68K package) has to run on
the host for this purpose.
- Routines for dynamic routing of interrupts to Fortran subroutines.
They simply exchange entries in the interrupt vector. This provides very fast
interrupt response directly by Fortran routines. The vector
locations are defaulted to a dummy routine which catches unassigned
interrupts.
The Floating Point Package (FPP) is a software substitute for the hardware
if this is not available. The package implements arithmetic for single-precision
(32-bit) floating point numbers. On such numbers, it performs
-
load, store
basic algebra
type conversions
standard arithmetic functions.
The package resembles a subset of the MC68881/2 floating point coprocessor.
It is entered by F-line emulation traps, i.e. the code generated by RTF
is as if a coprocessor were present. The following instructions are generated
by RTF and are emulated by the package:
-
Operation
fmove.l d0,fpn
fmove.l fpn,d0
fmove.s d0,fpn
fmove.s fpn,d0
fop.s d0,fpn
fop.x fpm,fpn
fbcc.w disp16
fscc.b d0
fmovem d(a5),list
fmovem list,d(a5)
fmovem (a7)+,list
fmovem list,-(a7)
fmove.l d0,fpcr
|
| Op-code
$f2004000 + $80*n
$f2006000 + $80*n
$f2004400 + $80*n
$f2006400 + $80*n
$f2004400 + $80*n +cop
$f2000000 + $400*m + $80*n + cop
$f2800000 + $1000*cc + disp16
$f2400000 + cc
$f22dd0000000 + $10000*clist + d
$f22df0000000 + $10000*clist + d
$f21fd000 + clist
$f227e000 + list
$f2009000
|
where the operations and codes are in detail:
-
op: add sub mul div cmp
cop: $22 $28 $23 $20 $38
op: neg abs sinh sqrt tanh atan asin atanh sin
cop: $1a $18 $02 $04 $09 $08 $0c $0d $0e
op: tan etox 10tx logn lg10 cosh acos cos
cop: $0f $10 $12 $14 $15 $19 $1c $1d
Not all of the transcendental functions are currently emulated.
The external number format is in IEEE 32-bit format:
-
The number is negative if sg=1; exponent and mantissa are not complemented.
The offset of the exponent is 127; i.e., $40000000 represents 2.0, $BFC00000
represents -1.5, etc.
The most significant mantissa bit is always set and omitted in the representation.
An all zero number represents the floating point zero. If the exponent
is zero, the entire number must be zero. This convention is chosen in order
to recognize most integers (up to 2**23) that are by error handled as floating
point numbers.
The internal (unpacked) representation of this package uses two longwords
for the eight pseudo FP registers F0-F7. The FP registers reside in the
32 bytes from -172(A6) onwards - save/restore of these software registers
are thus dummy operations.
-
-
Execution times of the software package are about 60 usec for basic
arithmetic and about 700 usec for the standard functions on a 10 MHz 68000.
This is about 20 times slower than the 16 MHz MC68881/2 FP coprocessor
used with the 68020/30. As programs are seldom pure floating point, the
overall speed remains still reasonable. For example, a matrix inversion
algorithm (Gauss elimination without pivot search) executes 12 times slower
on a 10 MHz 68000 than on a VAX 11/780.
The following operations which exist on 68020/30 but not on 68000 are
emulated in addition to the floating point coprocessor emulation:
-
32-bit integer multiply
32-bit integer divide
32-bit integer remainder
32-bit branch to subroutine
bit field extraction and insertion
The operations are in detail:
-
Operation
muls.l d0,dn
divs.l d0,dn
divsl.l d0,d0:dn
bsr.l dist32
bfextu dm{0:l},dn
bfins dm,dn{0:l}
|
| Op-code
$4c000800 + $1001*n
$4c400800 + $1001*n
$4c400800 + $1000*n
$61ff00000000 + dist32
$e9cnm000 + $40*o + l
o/l are constant or dr*20
$efcnm000 + $40*o + l
o/l are constant or dr*20
|
The input/output package provides the interface from the Fortran I/O
statements to the hardware involved. This interface comprises I/O conversions,
formatting, associating logical channels (units) with files via OPEN/CLOSE,
routing of requests to the target hardware devices, queueing of requests
if necessary, and performs the actions specific to the devices. If available,
the environment (operating system) is utilized for that purpose, but care
has been taken that stand-alone operation is possible.
The package is written in Fortran and also includes a small assembler
part.
In addition to the static assignment of subroutines to interrupts during
compilation described in 2.3., dynamic activation and de-activation at
run-time is provided by two subroutine calls:
CALL ACTIVATE(vectornumber,routine)
CALL PASSIVATE(vectornumber)
Vectornumber values are hardware-dependent as mentioned in 2.3.; routine
is a subroutine name which is declared EXTERNAL or is a formal parameter
of the routine calling ACTIVATE. The interrupt vector entry given by vectornumber
is set to point to routine. The effect of ACTIVATE is cancelled by PASSIVATE.
The interrupt vector entry is then reset to its default. This is represented
by the library subroutine IDLE which just types the message "unexpected
interrupt on line nnnn" in case of an interrupt not assigned to another
routine.
The integer function ICAMAD calculates the address of a CAMAC module
inside the 68K address space. The addressing convention is the one chosen
by CERN for VME and implemented in the CES or DataSud branch controller
modules. Arguments are branch, crate, station, subaddress, function, and
transfer size. All parameters are checked for validity. Abort and traceback
are initiated in case of error.
Example:
integer*2 @icam
integer*4 @jcam
@icam=icamad(b,0,n,a,f,1) ! calculate address of b,c=0,n,a,f
! .. the 1 stands for 16-bit size
idat=icam ! read from that module
...
idat2=icam ! second time with same address
@jcam=icamad(b,1,m,a,16,0) ! calculate an address in crate 1
! .. the 0 stands for 24-bit size
jcam=0 ! write zero into module
...
jcam=icam ! direct transfer between modules.