; 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