.TITL microFLOAT
;BCPL compatible microcoded FLOATING POINT ROUTINES
; R. Sproull 6/73
; Microcode version: J. Maleson 8/77

;Mu MicroFloatMC.MU
;PackMu MicroFloatMC.MB MicroFloatMC.BR 0 MicroFloatRamImage
;Asm MicroFloat.ASM
;Copy MicroFloat.BR ← MicroFloat.BR MicroFloatMC.BR LoadRam.BR

;Brief description of the routines:
;
;There are a variable number of floating point accumulators,
;numbered 0 to numACs-1
;These accumulators may be loaded, stored, operated on,
;and tested with the following operations.
;The microcode RAM must (obviously) be loaded with the
;appropriate microcode. This is accomplished by calling
;
LoadRam(MicroFloatRamImage)
;After this call, the memory space used for MicroFloatMC.BR and LoadRam.BR
;can be released. Microfloat.BR must remain resident, but it
;only takes up about 60 words. Note that the floating point
;routines can also be invoked as single assembly code instructrions,
;with op codes 70001 through 70021. The correspondence between
;op codes and floating point operations is:
microFMP=
70001
microFDV=
70002
microFAD=
70003
microFSB=
70004
microFLD=
70005
microFLDV=
70006
microFSTV=
70007
microFLDI=
70010
microFTR=
70011
microFNEG=
70012
microFSN=
70013
;removed for PRESS microFCM=
70014
microFST=
70015
microFLDDP=70016

microFSTDP=
70017
;removed for PRESS microDPAD=
70020
;removed for PRESS microDPSB=
70021
;removed for PRESS microFEXP=
70022
;
;Four words of memory are needed for each accumulator
;This memory space
must be provided by the user, by calling
;
; FPSetup (workArea)
;
workArea is the block of memory to be used for maintaining the ACs
;
workArea!0 is the number of accumulators to be used
;
The length of workArea must be at least (4*numACs)+1
;
The contents of workArea are not re-initialized, so that
;
reusing a previously used work area will have the effect
;
of restoring the values of the ACs to their previous state.
;
The static FPwork will be set to workArea
;
The call to FPSetup, loading the RAM, and the (shorter) work area
;
format are the only changes from the assembly coded routines.
;
; FLD (acnumber,arg)
;
Load the specified accumulator from source specified
;
by arg. See below for a definition of ’arg’.
;
; FST (acnumber, ptr-to-fp-number)
;
Store the contents of the accumulator into a 2-word
;
packed floating point format. Error if exponent is too
;
large or small to fit into the packed representation.
;
; FTR (acnumber) ==> integer
;
Truncate the floating point number in the accumu-
;
lator and return the integer value. Error if number
;
in ac cannot fit in an integer representation.
;
; FLDI (acnumber,integer)
;
Load-immediate of an accumulator with the integer
;
contents (signed 2’s complement).
;
; FNEG (acnumber)
;
Negate the contents of the accumulator.
;
; FAD (acnumber,arg)
;
Add the number in the accumulator to the number
;
specified by arg and leave the result in
;
the accumulator. See below for a definition of ’arg’.
;
; FSB (acnumber,arg)
;
Subtract the number specified by ’arg’ from the
;
number in the accumulator, and leave the result
;
in the accumulator.
;
; FML (acnumber,arg) [ also FMP ]
;
Multiply the number specified by ’arg’ by the number
;
in the accumulator, and leave the result in the ac.
;
; FDV (acnumber,arg)
;
Divide the contents of the accumulator by the number
;
specified by arg, and leave the result in the ac.
;
Error if attempt to divide by zero.
;
; FCM (acnumber,arg) ==> integer
;
Compare the number in the ac with the number
;
specified by ’arg’. Return
;
-1 IF ARG1 < ARG2
;
0 IF ARG1 = ARG2
;
1 IF ARG1 > ARG2
;
; FSN (acnumber) ==> integer
;
Return the sign of the floating point number.
;
-1if sign negative
;
0if value is exactly 0 (quick test!)
;
1if sign positive and number non-zero
;
; FEXP(acnum,increment)
Adds ’increment’ to the exponent of the
;
specified accumulator. The exponent is a binary power.
;
;For special hackers only:
; FLDV (acnumber,ptr-to-vector)
;
Read the 4-element vector into the internal
;
representation of a floating point number.
;
; FSTV (acnumber,ptr-to-vector)
;
Write the accumulator into the 4-element vector in
;
internal representation.
;
;’ARG’ in the above discussion means: if the 16-bit value is
;less than the number of accumulators, then use the
;contents of the accumulator of that number. Otherwise,
;the 16-bit value is assumed to be a pointer to a packed
;floating-point number.
;
;All of the functions listed above that do not have "==>"
;after them return their first argument as their value.
;
;A word about the packing format:
; The first word is:
;
sign -- 1 bit
;
exponent -- excess 128 format (8 bits)
;
will be complemented if sign negative
;
mantissa -- first 7 bits
; The second word is:
;
mantissa -- 16 more bits
;
;Note this format permits packed numbers to be tested for
;sign, to be compared (by comparing first words first), to
;be tested for zero (first word zero is sufficient), and
;(with some care) to be complemented.
;
;There are also some functions for dealing with 2-word
;fixed point numbers. The functions are chosen to be
;helpful to DDA scan-converters and the like.
;
;FSTDP(ac,ptr-to-dp-number)
;
Stores the contents of the floating point ac into
;
the specified double-precision number. First word
;
of the number is the integer part, second is fraction.
;
Two’s complement. Error if exponent too large.
;
;FLDDP(ac,ptr-to-dp-number)
;
Loads floating point ac from dp number.
;
;DPAD(a,b) => integer part of answer
;
a and b are both pointers to dp numbers. The dp
;
sum is formed, and stored in a.
;
;DPSB(a,b) => integer part of answer
;
Same as DPAD, but subtraction.
;
;If you wish to capture errors, put the address of a BCPL
;subroutine in the static FPerrprint. The routine will be
;called with one parameter:
;
0Exponent too large -- FTR
;
1Exponent too large -- FST
;
2Dividing by zero -- FDV
;
3Ac number out of range (any routine)
;
4Exponent too large -- FSTDP


.BEXTDoubleAdd,DoubleSub,DoubleShr;external routines

.NREL;MAKE RELOCATABLE

;DISPATCH TABLE
.ENT FLD
;LOAD
.ENT FST
;STORE
.ENT FTR
;TRUNCATE
.ENT FLDI
;LOAD IMMEDIATE
.ENT FNEG
;NEGATE
.ENT FAD
;ADD
.ENT FSB
;SUBTRACT
.ENT FML
;MULTIPLY
.ENT FMP
; (ANOTHER VERSION OF MULTIPLY)
.ENT FDV
;DIVIDE
.ENT FCM
;COMPARE
.ENT FSN
;SIGN
.ENT FLDV
;READ
.ENT FSTV
;WRITE
;removed for PRESS .ENT FEXP
;hack with exponent
.ENT FSTDP
;STORE DP
.ENT FLDDP
;LOAD DP
.ENT DPAD
;DP ADD
.ENT DPSB
;DP SUB
.ENT DPSHR
;DP Shift right
.ENT FPSetup
;set up work area
.ENT FPerrprint
;error printer routine
.ENT FPwork
;work area static

.SREL;STATICS FOR ENTRIES, ETC.

FLD:
.FLD
FST:
.FST
FTR:
.FTR
FLDI:
.FLDI
FNEG:
.FNEG
FAD:
.FAD
FSB:
.FSB
FML:
.FMP
FMP:
.FMP
FDV:
.FDV
FCM:
.FCM
FSN:
.FSN
FLDV:
.FLDV
FSTV:
.FSTV
;removed for PRESS FEXP: .FEXP
FSTDP:
.FSTDP
FLDDP:
.FLDDP
DPAD:
77400
DPSB:
77400
DPSHR:
77400

FPSetup:
.FPSetup
FPwork:
0;user MUST initialize by calling FPSetup

;POINTERS TO VARIOUS PROCEDURES
FPerrprint: .EPR
;dummy in case user fails to specify
locMicroErr:
microErr

.NREL

;%%ALTO%%
.DMR CALL =JSRII 0
.DMR JMPII =64000
;ALSO JSRII!!

;ROUTINES TO READ AND WRITE INTERNAL REPRESENTATION.

.FLDV:microFLDV
jmp 1,3
.FSTV:
microFSTV
jmp 1,3
.FSN:
microFSN
jmp 1,3
.FCM:
sta 1,saved1;FCM(a,b)
mov 0,1
lda 0,d32
microFLD;FLD(32,a)
lda 1,saved1
microFSB;FSB(32,b)
microFSN;FSN(32)
jmp 1,3
saved1:
0
d32:
40
.FNEG:
microFNEG
jmp 1,3
.FTR:
microFTR
jmp 1,3
.FLD:
microFLD
jmp 1,3
.FST:
microFST
jmp 1,3
.FAD:
microFAD
jmp 1,3
.FSB:
microFSB
jmp 1,3
.FLDI:
microFLDI
jmp 1,3
.FMP:
microFMP
jmp 1,3
.FDV:
microFDV
jmp 1,3
;removed for PRESS .FEXP:
microFEXP
;removed for PRESS
jmp 1,3
.FLDDP: microFLDDP
jmp 1,3
.FSTDP: microFSTDP
jmp 1,3
.DPAD:
DPAD
.DPSB:
DPSB
.DPSHR:
DPSHR
.DoubleAdd:
DoubleAdd
.DoubleSub:
DoubleSub
.DoubleShr:
DoubleShr

.MERR:
locMicroErr
.FPwork:
FPwork

;FPSetup(FPwork) set up work area
;FPwork!0=number of ACs
;length of FPwork is 1+4*numACs
.FPSetup:
sta 0,@.FPwork;save away for user
lda 1,@.MERR
70000;microcode initialization
lda 0,@.DoubleAdd
sta 0,@.DPAD
lda 0,@.DoubleSub
sta 0,@.DPSB
lda 0,@.DoubleShr
sta 0,@.DPSHR
jmp 1,3

microRet:
0
microErr: sta 3,microRet
CALL .ERRA;FPerrprint (initially points to location containing "jmp 1,3")
1
lda 3,microRet
jmp 1,3

;ERROR PRINTING MECHANISM
.ERRA:
FPerrprint
.EPR:
JMP 1,3;DUMMY ERROR PRINTER

.END