sys7.1-doc-wip/Interfaces/AIncludes/SANEMacs881.a

1479 lines
42 KiB
Plaintext
Raw Permalink Normal View History

2019-07-27 14:37:48 +00:00
; File: SANEMacs881.a
;
; Contains: xxx put contents here xxx
;
; Written by: xxx put writers here xxx
;
; Copyright: © 1991 by Apple Computer, Inc., all rights reserved.
;
; This file is used in these builds: ROM System
;
; Change History (most recent first):
;
; <7> 8/14/91 JL Added conditional include wrapper.
; <6> 6/14/91 JL Checked in official MPW 3.2ƒ version. Temporarily lost
; double-inclusion conditional; will be restored.
; <5> 3/13/91 JL Checking in MPW version. Removed precision code masks
; <4> 1/30/91 gbm sab, #38: Change the already including this file variable to
; all uppercase (for security reasons)
;
; To Do:
;
; File: SANEMacs881.a
;
; Version 3.0
; Spawned from SANEMacs.a on 21 Apr 87
; 25 Oct 88 now handles 882 frames
; 02 Jan 91 removed precision code masks
; Copyright Apple Computer, Inc. 1984-1988, 1991
; All Rights Reserved
;
; SANE Numerics -- These 881 SANE macros are an enhancement
; to the standard SANE macros found in SANEMacs.a; SANE trap
; calls are replaced with direct inline MC68881 code. These
; macros are MacII specific, i.e. they take advantage of the
; 020 and 881. With the exception of the size of extendeds,
; these macros are functionally equivalent to the standard
; macros. By keeping the interface standard but utilizing
; 96-bit extendeds instead of 80-bits, these macros serve as
; a bridge between the old 80-bit software SANE world and
; the new 96-bit hardware SANE world. In addition, these
; macros document, for the 020/881 programmer, the access of
; SANE routines, such as FRANDX, which aren't found on the
; MC68881 and must have their software exceptions mapped to
; hardware.
; YOU MUST RESIZE ALL YOUR 80-BIT EXTENDEDS TO 96-BITS
; BEFORE USING THESE MACROS.
; These 881 SANE macros preserve the 020/881 registers
; the same way the standard SANE macros do: all registers
; (except FP0,FP1) are preserved, except that REMAINDER
; still returns information in D0 and except that the
; scanners and formatter still destroy A0,A1,D0,D1.
MC68881
MACHINE MC68020
IF &TYPE('__INCLUDINGSANEMACS881__') = 'UNDEFINED' THEN
__INCLUDINGSANEMACS881__ SET 1
;———————————————————————————————————————————————————————————
; Operation code masks.
;———————————————————————————————————————————————————————————
FOADD EQU $0000 ; add
FOSUB EQU $0002 ; subtract
FOMUL EQU $0004 ; multiply
FODIV EQU $0006 ; divide
FOCMP EQU $0008 ; compare, no exception from unordered
FOCPX EQU $000A ; compare, signal invalid if unordered
FOREM EQU $000C ; remainder
FOZ2X EQU $000E ; convert to extended
FOX2Z EQU $0010 ; convert from extended
FOSQRT EQU $0012 ; square root
FORTI EQU $0014 ; round to integral value
FOTTI EQU $0016 ; truncate to integral value
FOSCALB EQU $0018 ; binary scale
FOLOGB EQU $001A ; binary log
FOCLASS EQU $001C ; classify
; UNDEFINED EQU $001E
FOSETENV EQU $0001 ; set environment
FOGETENV EQU $0003 ; get environment
FOSETHV EQU $0005 ; set halt vector
FOGETHV EQU $0007 ; get halt vector
FOD2B EQU $0009 ; convert decimal to binary
FOB2D EQU $000B ; convert binary to decimal
FONEG EQU $000D ; negate
FOABS EQU $000F ; absolute
FOCPYSGN EQU $0011 ; copy sign
FONEXT EQU $0013 ; next-after
FOSETXCP EQU $0015 ; set exception
FOPROCENTRY EQU $0017 ; procedure entry
FOPROCEXIT EQU $0019 ; procedure exit
FOTESTXCP EQU $001B ; test exception
; UNDEFINED EQU $001D
; UNDEFINED EQU $001F
;———————————————————————————————————————————————————————————
; Operand format masks.
;———————————————————————————————————————————————————————————
FFEXT EQU $0000 ; extended -- 80-bit float
FFDBL EQU $0800 ; double -- 64-bit float
FFSGL EQU $1000 ; single -- 32-bit float
FFINT EQU $2000 ; integer -- 16-bit integer
FFLNG EQU $2800 ; long int -- 32-bit integer
FFCOMP EQU $3000 ; comp -- 64-bit integer
;———————————————————————————————————————————————————————————
; Operations: operand addresses should already be on
; the stack, with the destination address on top. The
; suffix X, D, S, C, I, or L determines the format of the
; source operand -- extended, double, single, comp,
; integer, or long integer, respectively; the destination
; operand is always extended.
;———————————————————————————————————————————————————————————
;———————————————————————————————————————————————————————————
; Addition.
;———————————————————————————————————————————————————————————
MACRO
FADDX
fmove.x ([4,sp]),fp0
fadd.x ([sp]),fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
MACRO
FADDD
fmove.d ([4,sp]),fp0
fadd.x ([sp]),fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
MACRO
FADDS
fmove.s ([4,sp]),fp0
fadd.x ([sp]),fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
MACRO
FADDC
fmove.x ([sp]),fp1
jsr _FC2X
fadd fp1,fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
MACRO
FADDI
fmove.w ([4,sp]),fp0
fadd.x ([sp]),fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
MACRO
FADDL
fmove.l ([4,sp]),fp0
fadd.x ([sp]),fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
;———————————————————————————————————————————————————————————
; Subtraction.
;———————————————————————————————————————————————————————————
MACRO
FSUBX
fmove.x ([sp]),fp0
fsub.x ([4,sp]),fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
MACRO
FSUBD
fmove.x ([sp]),fp0
fsub.d ([4,sp]),fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
MACRO
FSUBS
fmove.x ([sp]),fp0
fsub.s ([4,sp]),fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
MACRO
FSUBC
fmove.x ([sp]),fp1
jsr _FC2X
fsub fp0,fp1
fmove fp1,fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
MACRO
FSUBI
fmove.x ([sp]),fp0
fsub.w ([4,sp]),fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
MACRO
FSUBL
fmove.x ([sp]),fp0
fsub.l ([4,sp]),fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
;———————————————————————————————————————————————————————————
; Multiplication.
;———————————————————————————————————————————————————————————
MACRO
FMULX
fmove.x ([4,sp]),fp0
fmul.x ([sp]),fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
MACRO
FMULD
fmove.d ([4,sp]),fp0
fmul.x ([sp]),fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
MACRO
FMULS
fmove.s ([4,sp]),fp0
fmul.x ([sp]),fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
MACRO
FMULC
fmove.x ([sp]),fp1
jsr _FC2X
fmul fp1,fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
MACRO
FMULI
fmove.w ([4,sp]),fp0
fmul.x ([sp]),fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
MACRO
FMULL
fmove.l ([4,sp]),fp0
fmul.x ([sp]),fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
;———————————————————————————————————————————————————————————
; Division.
;———————————————————————————————————————————————————————————
MACRO
FDIVX
fmove.x ([sp]),fp0
fdiv.x ([4,sp]),fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
MACRO
FDIVD
fmove.x ([sp]),fp0
fdiv.d ([4,sp]),fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
MACRO
FDIVS
fmove.x ([sp]),fp0
fdiv.s ([4,sp]),fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
MACRO
FDIVC
fmove.x ([sp]),fp1
jsr _FC2X
fdiv fp0,fp1
fmove fp1,fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
MACRO
FDIVI
fmove.x ([sp]),fp0
fdiv.w ([4,sp]),fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
MACRO
FDIVL
fmove.x ([sp]),fp0
fdiv.l ([4,sp]),fp0
fmove.x fp0,([sp])
addq #8,sp
ENDM
;———————————————————————————————————————————————————————————
; Square root.
;———————————————————————————————————————————————————————————
MACRO
FSQRTX
fsqrt.x ([sp]),fp0
fmove.x fp0,([sp])
addq #4,sp
ENDM
;———————————————————————————————————————————————————————————
; Round to integer, according to the current rounding mode.
;———————————————————————————————————————————————————————————
MACRO
FRINTX
fint.x ([sp]),fp0
fmove.x fp0,([sp])
addq #4,sp
ENDM
;———————————————————————————————————————————————————————————
; Truncate to integer, using round toward zero.
;———————————————————————————————————————————————————————————
MACRO
FTINTX
fintrz.x ([sp]),fp0
fmove.x fp0,([sp])
addq #4,sp
ENDM
;———————————————————————————————————————————————————————————
; Remainder. COMPATIBILITY: QUOT is moved to D0
;———————————————————————————————————————————————————————————
MACRO
FREMX
fmove.x ([sp]),fp0
frem.x ([4,sp]),fp0
fmove.x fp0,([sp])
fmove fpsr,d0
bfextu d0{8:8},d0
bpl.s @1
bclr #7,d0
neg.l d0
@1 addq #8,sp
ENDM
MACRO
FREMD
fmove.x ([sp]),fp0
frem.d ([4,sp]),fp0
fmove.x fp0,([sp])
fmove fpsr,d0
bfextu d0{8:8},d0
bpl.s @1
bclr #7,d0
neg.l d0
@1 addq #8,sp
ENDM
MACRO
FREMS
fmove.x ([sp]),fp0
frem.s ([4,sp]),fp0
fmove.x fp0,([sp])
fmove fpsr,d0
bfextu d0{8:8},d0
bpl.s @1
bclr #7,d0
neg.l d0
@1 addq #8,sp
ENDM
MACRO
FREMC
fmove.x ([sp]),fp1
jsr _FC2X
frem fp0,fp1
fmove fp1,fp0
fmove.x fp0,([sp])
fmove fpsr,d0
bfextu d0{8:8},d0
bpl.s @1
bclr #7,d0
neg.l d0
@1 addq #8,sp
ENDM
MACRO
FREMI
fmove.x ([sp]),fp0
frem.w ([4,sp]),fp0
fmove.x fp0,([sp])
fmove fpsr,d0
bfextu d0{8:8},d0
bpl.s @1
bclr #7,d0
neg.l d0
@1 addq #8,sp
ENDM
MACRO
FREML
fmove.x ([sp]),fp0
frem.l ([4,sp]),fp0
fmove.x fp0,([sp])
fmove fpsr,d0
bfextu d0{8:8},d0
bpl.s @1
bclr #7,d0
neg.l d0
@1 addq #8,sp
ENDM
;———————————————————————————————————————————————————————————
; Logb.
;———————————————————————————————————————————————————————————
MACRO
FLOGBX
fmove.x ([sp]),fp0
fbne.w @1
flog2 fp0
bra.s @3
@1 fmove fpsr,-(sp)
andi.l #$02000000,(sp)+
beq.s @2
fabs fp0
bra.s @3
@2 fgetexp fp0,fp0
@3 fmove.x fp0,([sp])
addq #4,sp
ENDM
;———————————————————————————————————————————————————————————
; Scalb.
;———————————————————————————————————————————————————————————
MACRO
FSCALBX
jsr _fprocENTRYsp
move.w ([sp]),([sp],2)
addq.l #2,(sp)
MOVE.W #FFINT+FOSCALB,-(SP)
_FP68K
fmove.x fp0,([12,sp])
jsr _fprocEXITsp
ENDM
;———————————————————————————————————————————————————————————
; Copy-sign.
;———————————————————————————————————————————————————————————
MACRO
FCPYSGNX
bclr #7,([4,sp])
tst.b ([sp])
bpl.s @1
bset #7,([sp])
@1 addq.l #8,sp
ENDM
;———————————————————————————————————————————————————————————
; Negate.
;———————————————————————————————————————————————————————————
MACRO
FNEGX
bchg.b #7,([sp])
addq.l #4,sp
ENDM
;———————————————————————————————————————————————————————————
; Absolute value.
;———————————————————————————————————————————————————————————
MACRO
FABSX
bclr.b #7,([sp])
addq.l #4,sp
ENDM
;———————————————————————————————————————————————————————————
; Next-after. NOTE: both operands are of the same
; format, as specified by the usual suffix.
;———————————————————————————————————————————————————————————
MACRO
FNEXTS
jsr _fprocENTRYsp
MOVE.W #FFSGL+FONEXT,-(SP)
_FP68K
jsr _fprocEXITsp
ENDM
MACRO
FNEXTD
jsr _fprocENTRYsp
MOVE.W #FFDBL+FONEXT,-(SP)
_FP68K
jsr _fprocEXITsp
ENDM
MACRO
FNEXTX
jsr _fprocENTRYsp
move.w ([sp]),([sp],2)
addq.l #2,(sp)
move.w ([4,sp]),([4,sp],2)
addq.l #2,4(sp)
MOVE.W #FFEXT+FONEXT,-(SP)
_FP68K
fmove.x fp0,([16,sp])
jsr _fprocEXITsp
ENDM
;———————————————————————————————————————————————————————————
; Conversion to extended.
;———————————————————————————————————————————————————————————
MACRO
FX2X
fmove.x ([4,sp]),fp0
fmove.x fp0,([sp])
addq.l #8,sp
ENDM
MACRO
FD2X
fmove.d ([4,sp]),fp0
fmove.x fp0,([sp])
addq.l #8,sp
ENDM
MACRO
FS2X
fmove.s ([4,sp]),fp0
fmove.x fp0,([sp])
addq.l #8,sp
ENDM
MACRO
FI2X
fmove.w ([4,sp]),fp0
fmove.x fp0,([sp])
addq.l #8,sp
ENDM
MACRO
FL2X
fmove.l ([4,sp]),fp0
fmove.x fp0,([sp])
addq.l #8,sp
ENDM
MACRO
FC2X
jsr _FC2X
addq #8,sp
ENDM
;———————————————————————————————————————————————————————————
; Conversion from extended.
;———————————————————————————————————————————————————————————
MACRO
FX2D
fmove.x ([4,sp]),fp0
fmove.d fp0,([sp])
addq.l #8,sp
ENDM
MACRO
FX2S
fmove.x ([4,sp]),fp0
fmove.s fp0,([sp])
addq.l #8,sp
ENDM
MACRO
FX2I
fmove.x ([4,sp]),fp0
fmove.w fp0,([sp])
addq.l #8,sp
ENDM
MACRO
FX2L
fmove.x ([4,sp]),fp0
fmove.l fp0,([sp])
addq.l #8,sp
ENDM
MACRO
FX2C
jsr _fprocENTRYsp
move.w ([4,sp]),([4,sp],2)
addq.l #2,4(sp)
MOVE.W #FFCOMP+FOX2Z,-(SP)
_FP68K
jsr _fprocEXITsp
ENDM
;———————————————————————————————————————————————————————————
; Binary to decimal conversion.
;———————————————————————————————————————————————————————————
MACRO
FX2DEC
jsr _fprocENTRYsp
move.l 12(sp),16(sp)
move.l 8(sp),12(sp)
move.l 28(sp),8(sp)
move.w ([4,sp]),([4,sp],2)
addq.l #2,4(sp)
MOVE.W #FFEXT+FOB2D,-(SP)
_FP68K
jsr _fprocEXITsp
ENDM
MACRO
FD2DEC
jsr _fprocENTRYsp
move.l 12(sp),16(sp)
move.l 8(sp),12(sp)
move.l 28(sp),8(sp)
MOVE.W #FFDBL+FOB2D,-(SP)
_FP68K
jsr _fprocEXITsp
ENDM
MACRO
FS2DEC
jsr _fprocENTRYsp
move.l 12(sp),16(sp)
move.l 8(sp),12(sp)
move.l 28(sp),8(sp)
MOVE.W #FFSGL+FOB2D,-(SP)
_FP68K
jsr _fprocEXITsp
ENDM
MACRO
FC2DEC
jsr _fprocENTRYsp
move.l 12(sp),16(sp)
move.l 8(sp),12(sp)
move.l 28(sp),8(sp)
MOVE.W #FFCOMP+FOB2D,-(SP)
_FP68K
jsr _fprocEXITsp
ENDM
MACRO
FI2DEC
jsr _fprocENTRYsp
move.l 12(sp),16(sp)
move.l 8(sp),12(sp)
move.l 28(sp),8(sp)
MOVE.W #FFINT+FOB2D,-(SP)
_FP68K
jsr _fprocEXITsp
ENDM
MACRO
FL2DEC
jsr _fprocENTRYsp
move.l 12(sp),16(sp)
move.l 8(sp),12(sp)
move.l 28(sp),8(sp)
MOVE.W #FFLNG+FOB2D,-(SP)
_FP68K
jsr _fprocEXITsp
ENDM
;———————————————————————————————————————————————————————————
; Decimal to binary conversion.
;———————————————————————————————————————————————————————————
MACRO
FDEC2X
jsr _fprocENTRYsp
addq.l #2,(sp)
MOVE.W #FFEXT+FOD2B,-(SP)
_FP68K
move.w ([12,sp],2),([12,sp])
jsr _fprocEXITsp
ENDM
MACRO
FDEC2D
jsr _fprocENTRYsp
MOVE.W #FFDBL+FOD2B,-(SP)
_FP68K
jsr _fprocEXITsp
ENDM
MACRO
FDEC2S
jsr _fprocENTRYsp
MOVE.W #FFSGL+FOD2B,-(SP)
_FP68K
jsr _fprocEXITsp
ENDM
MACRO
FDEC2C
jsr _fprocENTRYsp
MOVE.W #FFCOMP+FOD2B,-(SP)
_FP68K
jsr _fprocEXITsp
ENDM
MACRO
FDEC2I
jsr _fprocENTRYsp
MOVE.W #FFINT+FOD2B,-(SP)
_FP68K
jsr _fprocEXITsp
ENDM
MACRO
FDEC2L
jsr _fprocENTRYsp
MOVE.W #FFLNG+FOD2B,-(SP)
_FP68K
jsr _fprocEXITsp
ENDM
;———————————————————————————————————————————————————————————
; Compare, not signaling invalid on unordered. INCOMPATIBILITY: doesn't set 020's CCR
;———————————————————————————————————————————————————————————
MACRO
FCMPX
fmove.x ([sp]),fp0
fcmp.x ([4,sp]),fp0
addq.l #8,sp
ENDM
MACRO
FCMPD
fmove.x ([sp]),fp0
fcmp.d ([4,sp]),fp0
addq.l #8,sp
ENDM
MACRO
FCMPS
fmove.x ([sp]),fp0
fcmp.s ([4,sp]),fp0
addq.l #8,sp
ENDM
MACRO
FCMPC
fmovem.x ([sp]),fp1
jsr _FC2X
fcmp.x fp0,fp1
fmovem.x fp1,([sp])
addq.l #8,sp
ENDM
MACRO
FCMPI
fmove.x ([sp]),fp0
fcmp.w ([4,sp]),fp0
addq.l #8,sp
ENDM
MACRO
FCMPL
fmove.x ([sp]),fp0
fcmp.l ([4,sp]),fp0
addq.l #8,sp
ENDM
;———————————————————————————————————————————————————————————
; Compare, signaling invalid on unordered. INCOMPATIBILITY: doesn't set 020's CCR
;———————————————————————————————————————————————————————————
MACRO
FCPXX
fmove.x ([sp]),fp0
fcmp.x ([4,sp]),fp0
addq.l #8,sp
fbsf.w *+2
ENDM
MACRO
FCPXD
fmove.x ([sp]),fp0
fcmp.d ([4,sp]),fp0
addq.l #8,sp
fbsf.w *+2
ENDM
MACRO
FCPXS
fmove.x ([sp]),fp0
fcmp.s ([4,sp]),fp0
addq.l #8,sp
fbsf.w *+2
ENDM
MACRO
FCPXC
fmove.x ([sp]),fp1
jsr _FC2X
fcmp.x fp0,fp1
fmovem.x fp1,([sp])
addq.l #8,sp
fbsf.w *+2
ENDM
MACRO
FCPXI
fmove.x ([sp]),fp0
fcmp.w ([4,sp]),fp0
addq.l #8,sp
fbsf.w *+2
ENDM
MACRO
FCPXL
fmove.x ([sp]),fp0
fcmp.l ([4,sp]),fp0
addq.l #8,sp
fbsf.w *+2
ENDM
;———————————————————————————————————————————————————————————
; The following defines a set of so-called floating
; branches. They presume that the appropriate compare
; operation, FCMPz or FCPXz, precedes.
;———————————————————————————————————————————————————————————
MACRO
FBEQL
FBEQ.L &SYSLIST[1]
ENDM
MACRO
FBLTL
FBOLT.L &SYSLIST[1]
ENDM
MACRO
FBLEL
FBOLE.L &SYSLIST[1]
ENDM
MACRO
FBGTL
FBOGT.L &SYSLIST[1]
ENDM
MACRO
FBGEL
FBOGE.L &SYSLIST[1]
ENDM
MACRO
FBULTL
FBULT.L &SYSLIST[1]
ENDM
MACRO
FBULEL
FBULE.L &SYSLIST[1]
ENDM
MACRO
FBUGTL
FBUGT.L &SYSLIST[1]
ENDM
MACRO
FBUGEL
FBUGE.L &SYSLIST[1]
ENDM
MACRO
FBUL
FBUN.L &SYSLIST[1]
ENDM
MACRO
FBOL
FBOR.L &SYSLIST[1]
ENDM
MACRO
FBNEL
FBNE.L &SYSLIST[1]
ENDM
MACRO
FBUEL
FBUEQ.L &SYSLIST[1]
ENDM
MACRO
FBLGL
FBOGL.L &SYSLIST[1]
ENDM
;———————————————————————————————————————————————————————————
; Short branch versions.
;———————————————————————————————————————————————————————————
MACRO
FBEQS
FBEQ.W &SYSLIST[1]
ENDM
MACRO
FBLTS
FBOLT.W &SYSLIST[1]
ENDM
MACRO
FBLES
FBOLE.W &SYSLIST[1]
ENDM
MACRO
FBGTS
FBOGT.W &SYSLIST[1]
ENDM
MACRO
FBGES
FBOGE.W &SYSLIST[1]
ENDM
MACRO
FBULTS
FBULT.W &SYSLIST[1]
ENDM
MACRO
FBULES
FBULE.W &SYSLIST[1]
ENDM
MACRO
FBUGTS
FBUGT.W &SYSLIST[1]
ENDM
MACRO
FBUGES
FBUGE.W &SYSLIST[1]
ENDM
MACRO
FBUS
FBUN.W &SYSLIST[1]
ENDM
MACRO
FBOS
FBOR.W &SYSLIST[1]
ENDM
MACRO
FBNES
FBNE.W &SYSLIST[1]
ENDM
MACRO
FBUES
FBUEQ.W &SYSLIST[1]
ENDM
MACRO
FBLGS
FBOGL.W &SYSLIST[1]
ENDM
;———————————————————————————————————————————————————————————
; Class and sign inquiries.
;———————————————————————————————————————————————————————————
FCSNAN EQU 1 ; signaling NAN
FCQNAN EQU 2 ; quiet NAN
FCINF EQU 3 ; infinity
FCZERO EQU 4 ; zero
FCNORM EQU 5 ; normal number
FCDENORM EQU 6 ; denormal number
MACRO
FCLASSS
MOVE.W #FFSGL+FOCLASS,-(SP)
_FP68K
ENDM
MACRO
FCLASSD
MOVE.W #FFDBL+FOCLASS,-(SP)
_FP68K
ENDM
MACRO
FCLASSX
MOVE.W ([4,SP]),([4,SP],2)
ADDQ.L #2,4(SP)
MOVE.W #FFEXT+FOCLASS,-(SP)
_FP68K
ENDM
MACRO
FCLASSC
MOVE.W #FFCOMP+FOCLASS,-(SP)
_FP68K
ENDM
;———————————————————————————————————————————————————————————
; Bit indexes for bytes of floating point environment word.
;———————————————————————————————————————————————————————————
FBINVALID EQU 0 ; invalid operation
FBUFLOW EQU 1 ; underflow
FBOFLOW EQU 2 ; overflow
FBDIVZER EQU 3 ; division by zero
FBINEXACT EQU 4 ; inexact
FBRNDLO EQU 5 ; low bit of rounding mode
FBRNDHI EQU 6 ; high bit of rounding mode
FBLSTRND EQU 7 ; last round result bit
FBDBL EQU 5 ; double precision control
FBSGL EQU 6 ; single precision control
;———————————————————————————————————————————————————————————
; Get and set environment.
;———————————————————————————————————————————————————————————
MACRO
FGETENV
MOVE.W #FOGETENV,-(SP)
_FP68K
ENDM
MACRO
FSETENV
MOVE.W #FOSETENV,-(SP)
_FP68K
ENDM
;———————————————————————————————————————————————————————————
; Test and set exception.
;———————————————————————————————————————————————————————————
MACRO
FTESTXCP
MOVE.W #FOTESTXCP,-(SP)
_FP68K
ENDM
MACRO
FSETXCP
move.l (sp),-(sp)
jsr _fprocENTRYsp
MOVE.W #FOSETXCP,-(SP)
_FP68K
clr.l (sp)+
jsr _fprocEXITsp
ENDM
;———————————————————————————————————————————————————————————
; Procedure entry and exit.
;———————————————————————————————————————————————————————————
MACRO
FPROCENTRY
MOVE.W #FOPROCENTRY,-(SP)
_FP68K
ENDM
MACRO
FPROCEXIT
move.l (sp),-(sp)
jsr _fprocENTRYsp
MOVE.W #FOPROCEXIT,-(SP)
_FP68K
clr.l (sp)+
jsr _fprocEXITsp
ENDM
;———————————————————————————————————————————————————————————
; Get and set halt vector.
;———————————————————————————————————————————————————————————
MACRO
FGETHV
MOVE.W #FOGETHV,-(SP)
_FP68K
ENDM
MACRO
FSETHV
move.l ([sp]),$0c0
move.l ([sp]),$0c4
move.l ([sp]),$0c8
move.l ([sp]),$0cc
move.l ([sp]),$0d0
move.l ([sp]),$0d4
move.l ([sp]),$0d8
MOVE.W #FOSETHV,-(SP)
_FP68K
ENDM
;———————————————————————————————————————————————————————————
; Elementary function operation code masks.
;———————————————————————————————————————————————————————————
FOLNX EQU $0000 ; base-e log
FOLOG2X EQU $0002 ; base-2 log
FOLN1X EQU $0004 ; ln (1 + x)
FOLOG21X EQU $0006 ; log2 (1 + x)
FOEXPX EQU $0008 ; base-e exponential
FOEXP2X EQU $000A ; base-2 exponential
FOEXP1X EQU $000C ; exp (x) - 1
FOEXP21X EQU $000E ; exp2 (x) - 1
FOXPWRI EQU $8010 ; integer exponentiation
FOXPWRY EQU $8012 ; general exponentiation
FOCOMPOUND EQU $C014 ; compound
FOANNUITY EQU $C016 ; annuity
FOSINX EQU $0018 ; sine
FOCOSX EQU $001A ; cosine
FOTANX EQU $001C ; tangent
FOATANX EQU $001E ; arctangent
FORANDX EQU $0020 ; random
;———————————————————————————————————————————————————————————
; Elementary functions.
;———————————————————————————————————————————————————————————
MACRO
FLNX ; base-e log
flogn.x ([sp]),fp0
fmove.x fp0,([sp])
addq.l #4,sp
ENDM
MACRO
FLOG2X ; base-2 log
flog2.x ([sp]),fp0
fmove.x fp0,([sp])
addq.l #4,sp
ENDM
MACRO
FLN1X ; ln (1 + x)
flognp1.x ([sp]),fp0
fmove.x fp0,([sp])
addq.l #4,sp
ENDM
MACRO
FLOG21X ; log2 (1 + x)
move.l (sp),-(sp)
jsr _fprocENTRYsp
move.w ([sp]),([sp],2)
addq.l #2,(sp)
MOVE.W #FOLOG21X,-(SP)
_ELEMS68K
move.w ([sp],2),([sp])
clr.l (sp)+
jsr _fprocEXITsp
ENDM
MACRO
FEXPX ; base-e exponential
fetox.x ([sp]),fp0
fmove.x fp0,([sp])
addq.l #4,sp
ENDM
MACRO
FEXP2X ; base-2 exponential
ftwotox.x ([sp]),fp0
fmove.x fp0,([sp])
addq.l #4,sp
ENDM
MACRO
FEXP1X ; exp (x) - 1
fetoxm1.x ([sp]),fp0
fmove.x fp0,([sp])
addq.l #4,sp
ENDM
MACRO
FEXP21X ; exp2 (x) - 1
move.l (sp),-(sp)
jsr _fprocENTRYsp
move.w ([sp]),([sp],2)
addq.l #2,(sp)
MOVE.W #FOEXP21X,-(SP)
_ELEMS68K
move.w ([sp],2),([sp])
clr.l (sp)+
jsr _fprocEXITsp
ENDM
MACRO
FXPWRI ; integer exponential
jsr _fprocENTRYsp
move.w ([sp]),([sp],2)
addq.l #2,(sp)
MOVE.W #FOXPWRI,-(SP)
_ELEMS68K
move.w ([12,sp],2),([12,sp])
jsr _fprocEXITsp
ENDM
MACRO
FXPWRY ; general exponential
jsr _fprocENTRYsp
move.w ([4,sp]),([4,sp],2)
addq.l #2,4(sp)
move.w ([sp]),([sp],2)
addq.l #2,(sp)
MOVE.W #FOXPWRY,-(SP)
_ELEMS68K
move.w ([12,sp],2),([12,sp])
jsr _fprocEXITsp
ENDM
MACRO
FCOMPOUND ; compound
jsr _fprocENTRYsp
move.l 12(sp),16(sp)
move.l 8(sp),12(sp)
move.l 28(sp),8(sp)
move.w ([sp]),([sp],2)
addq.l #2,(sp)
move.w ([4,sp]),([4,sp],2)
addq.l #2,4(sp)
move.w ([8,sp]),([8,sp],2)
addq.l #2,8(sp)
MOVE.W #FOCOMPOUND,-(SP)
_ELEMS68K
move.w ([8,sp],2),([8,sp])
jsr _fprocEXITsp
ENDM
MACRO
FANNUITY ; annuity
jsr _fprocENTRYsp
move.l 12(sp),16(sp)
move.l 8(sp),12(sp)
move.l 28(sp),8(sp)
move.w ([sp]),([sp],2)
addq.l #2,(sp)
move.w ([4,sp]),([4,sp],2)
addq.l #2,4(sp)
move.w ([8,sp]),([8,sp],2)
addq.l #2,8(sp)
MOVE.W #FOANNUITY,-(SP)
_ELEMS68K
move.w ([8,sp],2),([8,sp])
jsr _fprocEXITsp
ENDM
MACRO
FSINX ; sine
fsin.x ([sp]),fp0
fmove.x fp0,([sp])
addq.l #4,sp
ENDM
MACRO
FCOSX ; cosine
fcos.x ([sp]),fp0
fmove.x fp0,([sp])
addq.l #4,sp
ENDM
MACRO
FTANX ; tangent
ftan.x ([sp]),fp0
fmove.x fp0,([sp])
addq.l #4,sp
ENDM
MACRO
FATANX ; arctangent
fatan.x ([sp]),fp0
fmove.x fp0,([sp])
addq.l #4,sp
ENDM
MACRO
FRANDX ; random number generator
move.l (sp),-(sp)
jsr _fprocENTRYsp
move.w ([sp]),([sp],2)
addq.l #2,(sp)
MOVE.W #FORANDX,-(SP)
_ELEMS68K
move.w ([sp],2),([sp])
clr.l (sp)+
jsr _fprocEXITsp
ENDM
;———————————————————————————————————————————————————————————
; Scanner and formatter operation code masks
;———————————————————————————————————————————————————————————
FOPSTR2DEC EQU $0002 ;Pascal string to decimal record
FOCSTR2DEC EQU $0004 ;C string to decimal record
FODEC2STR EQU $0003 ;decimal record to Pascal string
;———————————————————————————————————————————————————————————
; Scanner and formatter functions
;———————————————————————————————————————————————————————————
;Pascal string to decimal record
MACRO
FPSTR2DEC
MOVE.W #FOPSTR2DEC, -(SP)
_DecStr68K
ENDM
;C string to decimal record
MACRO
FCSTR2DEC
MOVE.W #FOCSTR2DEC, -(SP)
_DecStr68K
ENDM
;decimal record to Pascal string
MACRO
FDEC2STR
MOVE.W #FODEC2STR, -(SP)
_DecStr68K
ENDM
;———————————————————————————————————————————————————————————
; NaN codes.
;———————————————————————————————————————————————————————————
NANSQRT EQU 1 ; Invalid square root such as sqrt(-1).
NANADD EQU 2 ; Invalid addition such as +INF - +INF.
NANDIV EQU 4 ; Invalid division such as 0/0.
NANMUL EQU 8 ; Invalid multiply such as 0 * INF.
NANREM EQU 9 ; Invalid remainder or mod such as x REM 0.
NANASCBIN EQU 17 ; Attempt to convert invalid ASCII string.
NANCOMP EQU 20 ; Result of converting comp NaN to floating.
NANZERO EQU 21 ; Attempt to create a NaN with a zero code.
NANTRIG EQU 33 ; Invalid argument to trig routine.
NANINVTRIG EQU 34 ; Invalid argument to inverse trig routine.
NANLOG EQU 36 ; Invalid argument to log routine.
NANPOWER EQU 37 ; Invalid argument to x^i or x^y routine.
NANFINAN EQU 38 ; Invalid argument to financial function.
NANINIT EQU 255 ; Uninitialized storage.
*
* _FC2X converts a comp to a 96 bit extended
;
* push comp addr, then push destination addr, then jsr _FC2X .
* The addresses are NOT popped for you, i.e. the call is C style.
*
* The extended result is also left in fp0.
*
* All data and address registers are preserved.
*
_FC2X PROC
movem.l d0-d1,-(sp)
movem.l ([16,sp]),d0-d1
tst.l d1
bgt.s @1
beq.s @3
addq.l #1,d0
@1 fmove.l d0,fp0
fscale.w #32,fp0
fadd.l d1,fp0
bvc.s @2
fadd.s #"$5f800000",fp0
@2 movem.l (sp)+,d0-d1
fmove.x fp0,([4,sp])
rts
@3 neg.l d0
bvs.s @4
neg.l d0
bra.s @1
@4 fmove.s #"nan(20)",fp0
bra.s @2
ENDPROC
;———————————————————————————————————————————————————————————
; Procentry Special Macro. (Stack-based environment; doesn't change rnd and prec.)
;———————————————————————————————————————————————————————————
MACRO
FPROCENTRYSP
fmovem.l fpcr/fpsr,-(sp)
clr.l -(sp)
move.l 4(sp),-(sp)
and.l #$ff,(sp)
fmovem.l (sp)+,fpcr/fpsr
ENDM
*
* Subroutines _fprocENTRYsp and _fprocEXITsp bracket two argument SANE ROM calls,
* causing their software exceptions to happen in hardware.
*
* ENTRY: STACK: rtnaddr < DSTaddr < SRCaddr
* EXIT: STACK: DSTaddr < SRCaddr < FPCR < FPSR < (0).L < DSTaddr < SRCaddr
*
* All data and address registers are preserved. FP1 is scratched.
*
_fprocENTRYsp PROC
fmovem.l (sp)+,fpiar
clr.l -(sp)
fmovem (sp),fp0
FPROCENTRYSP
fmovem fp0,-(sp)
clr.l (sp)+
fmovem.l fpiar,-(sp)
rts
ENDPROC
*
* Subroutines _fprocEXITsp and _fprocENTRYsp bracket two argument SANE ROM calls,
* causing their software exceptions to happen in hardware.
*
* ENTRY: STACK: rtnaddr < FPCR < FPSR < (0).L < DSTaddr < SRCaddr
* EXIT: STACK:
*
* All data and address registers are preserved. FP1 is scratched.
*
_fprocEXITsp PROC
FMOVE.W D1,FP1
FMOVE.L FPSR,-(SP)
MOVE.W 2(SP),D1
CLR.L (SP)+
FMOVEM.L 4(SP),FPCR/FPSR
OR.W D1,10(SP)
AND.W 5(SP),D1 ; Yes, 5
FMOVE.L 8(SP),FPSR
TST.B D1
BEQ.S @1
FNOP
NOP
FSAVE -(SP)
CLR.W D1
MOVE.B 1(SP),D1
BCLR #3,(SP,D1.W)
FRESTORE (SP)+
FNOP
@1 FMOVE.W FP1,D1
MOVE.L (SP),20(SP)
ADDA.W #20,SP
RTS
ENDPROC
ENDIF ; ...already included