sys7.1-doc-wip/Interfaces/AIncludes/SANEMacs881.a
2019-07-27 22:37:48 +08:00

1479 lines
42 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; 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