.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