;
;	File:		FPCtrl.a
;
;	Contains:	Floating Point Stuff
;
;	Written by:	Jerome T. Coonen
;
;	Copyright:	© 1982-1990 by Apple Computer, Inc., all rights reserved.
;
;   This file is used in these builds:   Mac32
;
;	Change History (most recent first):
;
;		 <3>	 9/17/90	BG		Removed <2>. 040s are behaving more reliably now.
;		 <2>	  7/4/90	BG		Added EclipseNOPs for flakey 040s.
;	   <1.1>	11/11/88	CCH		Fixed Header.
;	   <1.0>	 11/9/88	CCH		Adding to EASE.
;	   <1.0>	 2/12/88	BBM		Adding file for the first time into EASEÉ

;-----------------------------------------------------------
;-----------------------------------------------------------
; old FPControl
;-----------------------------------------------------------
;-----------------------------------------------------------
;
;-----------------------------------------------------------
; 04JUL82: WRITTEN BY JEROME COONEN
; 29AUG82: ACCESS TO STATE MADE EXPLICIT HERE. (JTC)
; 12OCT82: CLEAR D0.W TO GET QUO IN REM; RND-UP BIT. (JTC)
; 12DEC82: DON'T CLEAR D0.W HERE -- LET REM DO IT ALL (JTC)
; 28DEC82: ADD LOGBX AND SCALBX (JTC).
; 13APR83: ADD COMMENT ABOUT LABEL POP3 (JTC).
; 29APR83: ADD CLASS (JTC).
; 09MAY83: MAJOR CHANGES: SEE FPDRIVER. (JTC)
; 25AUG83: Change to Lisa Sane_Environ (JTC).
; 01NOV83: MOVE PRECISION CONTROL TO MODES (JTC).
; 15APR84: SOME CODE MOVEMENT FOR LISABUG'S SAKE (JTC & DGH).
; 14JAN85: MDS (JTC)
; 26MAR85: COLLECT FPCONTROL, FPUNPACK, FPNANS, FPCOERCE, FPPACK!
;			LISA ENVIRONMENT NAME = %%%ZENVIRON.
; 03APR85: MODIFY CALL OUT TO HALT RTN USING ROMRSRC EQU. (JTC)
; 31JUL85: BACK TO PORKSHOP.													<31JUL85>
;
;-----------------------------------------------------------


			BLANKS		ON
			STRING		ASIS

			IF		 FPFORMAC+FPFORDEB THEN  ; PACKAGE HEADER MESSES UP LISABUG

			BRA.S	FPBEGIN

			DC.W	 $00				 ; MAC SPECIFIC STUFF
			DC.L	 ('PACK')
			DC.W	 $4
			DC.W	$0002				; VERSION 2 							<26MAR85>

			ENDIF

;-----------------------------------------------------------
; FOR TESTING, DEFINE STATEADRS RIGHT HERE
;-----------------------------------------------------------
			IF		 FPFORDEB THEN
STATEADRS:
			DC.W	 0
			DC.W	 0
			DC.W	 0
			ENDIF

;-----------------------------------------------------------
; THIS IS THE SOLE ENTRY POINT OF THE PACKAGE.
; THE STACK HAS THE FORM:
;	<RET> <OPWORD> <ADRS1> <ADRS2> <ADRS3>
; WHERE THE NUMBER OF ADDRESSES DEPENDS ON THE OPERATION.
; MOST USE 2, SOME 1, ONLY BIN->DEC USES 3.
;
; FIRST GROW THE STACK TO HOLD: <TRAP VECTOR> <BYTE COUNT>
; BELOW <RET> IN CASE A TRAP IS TAKEN.
;
; THEN SAVE REGISTERS D0-D7, A0-A4.
;-----------------------------------------------------------
FPBEGIN:
			LINK	A6,#-2				; RESERVE CNT WORD
			MOVEM.L D0-D7/A0-A4,-(SP)

;-----------------------------------------------------------
;
; GET POINTER TO STATE AREA IN A0, USING SYSTEM CONVENTION.
; SAMPLE USES ARE:
;
;	(DEBUGGING)
;		LEA STATEADRS,A0
;
;	(LISA)
;		Get state address from library routine.
;
;	(MACINTOSH)
;		MOVEA.W #FPState,A0
;			...WHERE FPState IS DEFINED IN
;			TOOLEQU.TEXT, TO BE INCLUDED AT THE
;			TOP OF THE PROGRAM IN FPDRIVER.TEXT
;
;
;-----------------------------------------------------------
			IF		 FPFORMAC THEN
			MOVEA.W #FPState,A0
			ENDIF

			IF		 FPFORDEB THEN
			LEA 	STATEADRS,A0
			ENDIF

			IF		 FPFORLISA THEN
			SUBQ.L	#4,SP				; MAKE WAY FOR PTR

			; THE FOLLOWING LABELS DELETED FOR MDS BUG							<26MAR85>
			;	XREF	%%%ZEnviron 		; GOOFY LISA LABEL					<26Mar85>
			;	JSR 	%%%ZEnviron 		; COMPUTE STATE ADRS				<26Mar85>

			MOVEA.L (SP)+,A0
			ENDIF

			BRA.S	FPCOM				; NOW DO IT

;-----------------------------------------------------------
; THIS IS A TABLE OF INFORMATION BITS FOR THE VARIOUS
; OPERATIONS.  SEE COMMENT BELOW FOR EXPLANATION
;-----------------------------------------------------------
OPMASKS:
			DC.W	 $0E1				 ; ADD
			DC.W	 $0E1				 ; SUB
			DC.W	 $0E1				 ; MUL
			DC.W	 $0E1				 ; DIV
			DC.W	 $0C1				 ; CMP
			DC.W	 $0C1				 ; CMPX
			DC.W	 $0E1				 ; REM
			DC.W	 $061				 ; 2EXT
			DC.W	 $161				 ; EXT2
			DC.W	 $0A0				 ; SQRT
			DC.W	 $0A0				 ; RINT
			DC.W	 $0A0				 ; TINT
			DC.W	 $0A1				 ; SCALB -- LIKE SQRT, LEAVE INT
			DC.W	 $0A0				 ; LOGB -- LIKE SQRT
			DC.W	 $041				 ; CLASS -- SRC IN, INT PTR IS DST

			IF		 FPFORlisa THEN
			DEBUGEND	'FP68K          '
			ENDIF

;-----------------------------------------------------------
; ALTERNATIVE ENTRY POINT TO BYPASS RECALC OF STATE PTR.
;-----------------------------------------------------------
REFP68K:
			LINK	A6,#-2				; RESERVE CNT WORD
			MOVEM.L D0-D7/A0-A4,-(SP)

FPCOM:

;-----------------------------------------------------------
; GET OPWORD INTO D6.LO; AFTER DECODING, WILL GO TO D6.HI.
;-----------------------------------------------------------
			MOVE.W	LKOP(A6),D6

;-----------------------------------------------------------
; HANDLE ODD INSTRUCTIONS (STATE AND BIN-DEC) ELSEWHERE.
;-----------------------------------------------------------
			MOVEQ	#OPAMASK,D7 		; ISOLATE OP INDEX
			AND.W	D6,D7

			BCLR	#0,D6				; TEST AND CLEAR ODD BIT
			BNE 	ODDBALL

;-----------------------------------------------------------
; FOR ARITHMETIC OPERATIONS, CLEAR ROUND INCREMENT BIT IN
; LOW BYTE OF STATE WORD.
;-----------------------------------------------------------
			BCLR	#RNDINC,1(A0)

;-----------------------------------------------------------
; SAVE INDEX IN D7.LO FOR LATER JUMP.
; PICK UP USEFUL INFO BITS FROM TABLE, AFTER WHICH HAVE:
;	8000 - IF SINGLE OP
;	4000 - IF DOUBLE OP
;	3800 - "NONEXTENDED" OPERAND -- WILL BE SRC FORMAT
;	0100 - IF "NONEXTENDED" IS DST
;	0700 - WILL BE DST FORMAT
;	0080 - IF DST IS INPUT
;	0040 - IF SRC IS INPUT
;	0020 - IF DST IS OUTPUT (IDENTIFIES COMPARISONS)
;	001E - OP CODE
;	0001 - IF 2 ADDRESSES ON STACK
;-----------------------------------------------------------
			IF		 PCOK THEN
			OR.W	OPMASKS(PC,D7),D6
			ELSE
			OR.W	OPMASKS(D7),D6
			ENDIF

;-----------------------------------------------------------
; TWO CASES MUST BE DISTINGUISHED:
;	DST = EXTENDED, SRC = ANY	   (USUAL)
;	DST = ANY	SRC = EXTENDED	   (CONVERSIONS)
; THE "ANY" FORMAT IS IN BITS 3800 (SRC).  BIT 0100
; DETERMINES WHETHER IT SHOULD BE DST IN BITS 0700.
; AFTER TEST ABOVE HAVE FORMAT BITS ISOLATED IN D0.
;
; IF FORMAT GOVERNS DST OPERAND, IT OVERRIDES 2 LEADING
; CONTROL BITS.  NOTE THAT EVEN EXTRANEOUS INTEGER BITS
; OVERRIDE CONTROL BITS, BUT THEY HAVE NO EFFECT.
;
; IN ANY CASE, MOVE PRECISION CONTROL BITS TO HIGH BITS OF
; D6.
;-----------------------------------------------------------
			MOVEQ	#PRECMSK,D0 		; GET ONLY PRECISION CONTROL
			AND.B	1(A0),D0
			ROR.W	#7,D0				; ALIGN $0060 AS $C000
			OR.W	D0,D6

			BTST	#8,D6
			BEQ.S	@2

			MOVE.W	D6,D0				; SAVE FORMAT BITS
			ANDI.W	#$00FF,D6			; KILL ALL FORMAT BITS

			ANDI.W	#$3800,D0			; ISOLATE FORMAT BITS
			MOVE.W	D0,D1				; COPY FOR CONTROL BITS
			LSL.W	#3,D1				; ALIGN 2 TRAILING BITS
			ROR.W	#3,D0				; SRC -> DST POSITION
			OR.W	D0,D6
			OR.W	D1,D6
@2:

;-----------------------------------------------------------
; PLACE OPWORD IN D6.HI WHERE IT WILL STAY.
; INIT TO ZERO D2,3 = INDEXES FOR CASES,
; D6.LO = FLAGS & SIGNS.
; BY NOW, D7.HI = JUNK, D7.LO = OPERATION INDEX.
;-----------------------------------------------------------
			SWAP	D6
			CLR.L	D2
			MOVE.L	D2,D3
			MOVE.W	D2,D6

;-----------------------------------------------------------
; POST-DECODE MILESTONE ++++++++++++++++++++++++++++++++++ .
;-----------------------------------------------------------

;-----------------------------------------------------------
; NOW UNPACK OPERANDS, AS NEEDED.  DST, THEN SRC.
; LAST OPERAND IS IN D4,5/A4/D6.B.#7
; FIRST OPERAND, IF 2, IS IN A1,2/A3/D6.B.#6
; UNPACK ROUTINE EXPECTS (FORMAT*2) IN DO AND ADRS IN A3.
;-----------------------------------------------------------
			BTST	#DSTIN+16,D6
			BEQ.S	@3

			MOVE.L	D6,D0				; GET OPWORD AND ALIGN DST
			SWAP	D0
			ROR.W	#7,D0
			MOVEA.L LKADR1(A6),A3		; DST ADDRESS
			BSR 	UNPACK
@3:

;-----------------------------------------------------------
; IF SOURCE IN, MOVE DST OP OVER (EVEN IF NONE INPUT)
; ALSO, BUMP INDEXES IN D2,D3.
; IN ORDER TO USE A3 TO CALL UNPACK, MUST SAVE DST EXP (IN
; A4) ACCROSS CALL, THEN RESTORE TO A3.
;-----------------------------------------------------------
			BTST	#SRCIN+16,D6
			BEQ.S	@4

			MOVEA.L D4,A1				; HI BITS
			MOVEA.L D5,A2				; LO BITS
			MOVE.L	A4,-(SP)			; SAVE EXP ON STACK FOR CALL
			ROR.B	#1,D6				; SIGN

			ADD.W	D2,D2				; NAN INDEX (NEG, 2, 4, 6)
			MOVE.W	D3,D0				; NUM INDEX (0 - 16)
			ADD.W	D3,D3
			ADD.W	D0,D3

			MOVE.L	D6,D0
			SWAP	D0
			ROL.W	#6,D0
			MOVEA.L LKADR2(A6),A3		; SRC ADDRESS
			BSR 	UNPACK
			MOVEA.L (SP)+,A3			; RESTORE DST EXP
@4:

;-----------------------------------------------------------
; CONVENIENT HERE TO PUT XOR OF SIGNS IN D6(#5).
;-----------------------------------------------------------
			ASL.B	#1,D6				; V = XOR OR SIGNS
			BVC.S	@6
			BSET	#6,D6
@6:
			ROXR.B	#1,D6

;-----------------------------------------------------------
; POST-UNPACK MILESTONE +++++++++++++++++++++++++++++++++++.
;-----------------------------------------------------------

;-----------------------------------------------------------
; NOW PUSH A RETURN ADDRESS AND JUMP TO 3 CASES.
; REMEMBER OPERATION INDEX IN D7, WHICH MUST BE ZEROED.
;-----------------------------------------------------------
			MOVE.W	D7,D0				; FREE D7 FOR INIT
			CLR.L	D7

			IF		 PCOK THEN
			PEA 	PREPACK(PC) 		; WHERE TO COME BACK TO
			ELSE
			PEA 	PREPACK
			ENDIF

			TST.W	D2					; NANS DISCOVERED?
			BNE 	NANS

;-----------------------------------------------------------
; DO-ARITHMETIC MILESTONE ++++++++++++++++++++++++++++++++ .
;-----------------------------------------------------------

ARITHOP:
			IF		 PCOK THEN
			MOVE.W	ARITHTAB(PC,D0),D0	; GET INDEX
			JMP 	ARITHOP(PC,D0)
			ELSE
			MOVE.W	ARITHTAB(D0),D0
			JMP 	ARITHOP(D0)
			ENDIF

;-----------------------------------------------------------
; JUMP TO ARITHMETIC ROUTINE BASED ON INDEX SAVED IN D7.
;-----------------------------------------------------------
ARITHTAB:
			DC.W	 ADDTOP-ARITHOP
			DC.W	 SUBTOP-ARITHOP
			DC.W	 MULTOP-ARITHOP
			DC.W	 DIVTOP-ARITHOP
			DC.W	 CMPTOP-ARITHOP
			DC.W	 CMPTOP-ARITHOP 	 ; CMPX NOT  SPECIAL
			DC.W	 REMTOP-ARITHOP
			DC.W	 CVT2E-ARITHOP
			DC.W	 CVTE2-ARITHOP
			DC.W	 SQRTTOP-ARITHOP
			DC.W	 RINT-ARITHOP
			DC.W	 TINT-ARITHOP
			DC.W	 SCALBTOP-ARITHOP
			DC.W	 LOGBTOP-ARITHOP
			DC.W	 CLASSTOP-ARITHOP


;-----------------------------------------------------------
; PRE-PACK MILESTONE +++++++++++++++++++++++++++++++++++++ .
;-----------------------------------------------------------

;-----------------------------------------------------------
; PACK AND DELIVER IF OUTPUT OPERAND (SKIP COMPARES)
;-----------------------------------------------------------
PREPACK:
			BTST	#DSTOUT+16,D6
			BEQ.S	CHKERR

			MOVE.L	D6,D0				; GET OPWORD AND ALIGN DST
			SWAP	D0
			ROR.W	#7,D0
			BSR 	PACK

;-----------------------------------------------------------
; ALIGN CCR BITS FROM D7.HI TO D7.LO.
; OR ERROR FLAGS INTO STATE WORD, STUFF STATE WORD, AND
; CHECK FOR A TRAP.
;-----------------------------------------------------------
CHKERR:
			SWAP	D7					; RIGHT ALIGN CCR BITS

			MOVE.W	(A0),D0 			; GET STATE WORD
			CLR.B	D6					; KILL SIGNS
			OR.W	D6,D0
			MOVE.W	D0,(A0)+			; BUMP ADRS TO VECTOR

			ROR.W	#8,D6				; ALIGN BYTES
			AND.W	D6,D0
			BEQ.S	PASTHALT			; ZERO IF NO TRAP

;-----------------------------------------------------------
; TO SET UP FOR TRAP:
;	HAVE D0 ON TOP OF STACK.
;	PUSH CCR TO HAVE 3-WORD STRUCTURE
;	PUSH ADDRESS OF 3-WORD STRUCTURE
;	BLOCK MOVE	OPCODE < ADR1 < ADR2 < ADR3 < REGADR
;	  TO STACK
;	CALL HALT PROCEDURE, EXPECTING PASCAL CONVENTIONS TO
;		BE HONORED.
; THE BLOCK MOVE CAN BE DONE WITH A PAIR OF MOVEM'S SO LONG
; AS AN EXTRA WORD IS COPIED (TO HAVE A WHOLE NUMBER OF
; LONGS).
;-----------------------------------------------------------


			MOVE.W	D7,-(SP)			; SAVE CCR BELOW D0
			MOVE.W	d0,-(sp)
			PEA 	(SP)				; ADDRESS OF CCR/D0

			MOVEM.L LKRET+2(A6),D0-D3
			MOVEM.L D0-D3,-(SP)
			ADDQ.L	#2,SP				; KILL EXTRA WORD

;-----------------------------------------------------------
; IN MAC ENVIRONMENT, MUST LOCK MATH PACKAGE BEFORE CALLING
; EXTERNAL PROCEDURE THAT WILL EXPECT TO RETURN.
;-----------------------------------------------------------

			IF		 ROMRSRC THEN

			MOVE.L	AppPacks+16,A4		; GET FP68K HANDLE
			MOVE.B	(A4),D7 			; SAVE STATE OF LOCK BIT, CHANGED TO BYTE		<03APR85>
			BSET	#Lock,(A4)			; FORCE LOCKING
			MOVEA.L (A0),A0 			; GET VECTOR ADRS
			JSR 	(A0)
			MOVE.B	D7,(A4) 			; RESTORE LOCK BIT STATE, BYTE			<03APR85>

			ELSE

			MOVEA.L (A0),A0
			JSR 	(A0)

			ENDIF

			MOVE.L	(SP)+,D7			; RESTORE CCR BITS

;-----------------------------------------------------------
; AFTER TRAP JUST RESTORE REGISTERS, KILL STACK STUFF, AND
; RETURN.  TRICK: LOAD INCREMENT TO STACK JUST BELOW REGS,
; SO ACCESSIBLE AFTER MOVEM.L.
;-----------------------------------------------------------
PASTHALT:
			BTST	#TWOADRS+16,D6
			BEQ.S	POP1
POP2:
			MOVEQ	#STKREM2,D0
			MOVEQ	#LKADR2,D1
			BRA.S	POPIT
POP1:
			MOVEQ	#STKREM1,D0
			MOVEQ	#LKADR1,D1
POPIT:
			MOVE.W	D0,LKCNT(A6)		; KILL COUNT
			MOVE.L	LKRET(A6),0(A6,D1)	; MOVE RETURN DOWN
			MOVEA.L (A6),A6 			; UNLINK MANUALLY
			MOVE	D7,CCR
			MOVEM.L (SP)+,D0-D7/A0-A4
			ADDA.W	(SP),SP
			RTS

;-----------------------------------------------------------
; THE ONLY THREE-ADDRESS OPERATION IS BINARY TO DECIMAL
; CONVERSION.  POP3 IS JUMPED TO FROM THE END OF THAT OP.
; NOTE THAT BIN2DEC CANNOT ITSELF TRAP, SO THE CODE AFTER
; @1 ABOVE IS IRRELEVANT.
;-----------------------------------------------------------
POP3:
			MOVEQ	#STKREM3,D0
			MOVEQ	#LKADR3,D1
			BRA.S	POPIT



;-----------------------------------------------------------
;-----------------------------------------------------------
; old FPUnpack...
;-----------------------------------------------------------
;-----------------------------------------------------------

;-----------------------------------------------------------
; 03JUL82: WRITTEN BY JEROME COONEN
; 10AUG82: MINOR CLEANUPS (JTC)
; 18JAN83: FORCE COMP NAN CODE ON UNPACK OF COMP64.
; 29APR83: CLASS OPERATION NEEDS TO KNOW WHEN DENORM IS
;	UNPACKED.  USE HI BIT OF HI WORD OF D3, THE REG
;	HOLDING THE OPERAND TYPE INFO. (JTC)
; 09JUN83: USE A3 FOR ADRS, RATHER THAN A5 (JTC).
; 01NOV83: ALL NANS UNPACKED THE SAME; INVALID SET FOR SIGNALING (JTC).
; 14JAN85: MDS (JTC)
; 26MAR85: FIXED CLASS-COMP BUG AT LABEL UNPCUNR.  CHANGE STATE OF NAN BIT. 		<26MAR85>
;
; ASSUME REGISTER MASK: POST-DECODE, WITH DIRTY INDEX IN D0.
; UNPACK DST, SRC IN TURN, IF INPUT, AND SET UP D2 WITH
;	NAN INFORMATION, D3 WITH NUMBER INFORMATION.
;
;	D2:  2 --> LATTER OPERAND IS NAN
;		 4 --> FIRST OF TWO OPERANDS IS NAN
;		 6 --> BOTH NANS
;
;	D3:  0 --> BOTH ARE NUMS
;		 2 --> FORMER IS NUM, LATTER IS 0
;		 4 --> FORMER IS NUM, LATTER IS INF
;		 6 --> FORMER IS 0,   LATTER IS NUM
;		 8 --> BOTH ARE 0
;		10 --> FORMER IS 0,   LATTER IS INF
;		12 --> FORMER IS INF, LATTER IS NUM
;		14 --> FORMER IS INF, LATTER IS 0
;		16 --> BOTH ARE INF
;
; INPUT OPERAND ADDRESS IN A3.
; UNPACK LEAVES SIGN IN HIGH BIT OF D6 BYTE, EXP IN A4, AND
; DIGITS IN D4,5.  SINCE INPUT INTEGERS ARE ALWAYS CONVERTED
; TO EXTENDED, LOAD AND NORMALIZE THEM.
; UNPACKING IS DONE IN TWO STAGES; FIRST, UNPACK AS ABOVE
; BUT LEAVE A WORD EXP IN D0; SECOND, SET THE CONTROL BITS
; FOR SPECIAL CASES AND MOVE THE EXP TO A4.
; THE ADDRESS IN A3 IS UNCHANGED, IN CASE IT'S NEEDED FOR
; OUTPUT.
;-----------------------------------------------------------

;-----------------------------------------------------------
; UNPACK-TOP MILESTONE +++++++++++++++++++++++++++++++++++ .
;-----------------------------------------------------------

UNPACK:
;-----------------------------------------------------------
; HANDY TO KILL SIGNIFICANT BITS AT OUTSET; ALREADY ROOM FOR
; SIGN.
;-----------------------------------------------------------
			CLR.L	D4					; HANDY TO KILL BITS HERE
			MOVE.L	D4,D5

			ANDI.W	#$000E,D0			; KILL EXTRANEOUS BITS

			IF		 PCOK THEN
			MOVE.W	UNPCASE(PC,D0),D0
			JMP 	UNPACK(PC,D0)
			ELSE
			MOVE.W	UNPCASE(D0),D0
			JMP 	UNPACK(D0)
			ENDIF

UNPCASE:
			DC.W	 UNPEXT-UNPACK
			DC.W	 UNPDBL-UNPACK
			DC.W	 UNPSGL-UNPACK
			DC.W	 UNPEXT-UNPACK
			DC.W	 UNPI16-UNPACK
			DC.W	 UNPI32-UNPACK
			DC.W	 UNPC64-UNPACK


;-----------------------------------------------------------
; INT16 HAS SPECIAL CASE 0, ELSE NORMALIZE AND GO.
;-----------------------------------------------------------
UNPI16:
			MOVEQ	#15,D0				; SET EXP FOR INTEGER
			MOVE.W	(A3),D4 			; GET OPERAND
			SWAP	D4					; LEFT ALIGN
			BRA.S	UNPIGEN

;-----------------------------------------------------------
; INT32 HAS SPECIAL CASE 0, ELSE NORMALIZE AND GO.
;-----------------------------------------------------------
UNPI32:
			MOVEQ	#31,D0				; SET EXP FOR INTEGER
			MOVE.L	(A3),D4 			; GET OPERAND
			BRA.S	UNPIGEN

;-----------------------------------------------------------
; COMP64 HAS SPECIAL CASES 0 AND INF, ELSE NORMALIZE AND GO.
;-----------------------------------------------------------
UNPC64:
			MOVEQ	#63,D0				; SET EXP FOR INTEGER
			MOVE.L	(A3),D4 			; GET HI OPERAND
			MOVE.L	4(A3),D5			; GET LO OPERAND
			BEQ.S	@7					; HAVE REGULAR NUMBER

			TST.L	D4
			BRA.S	UNPCGEN
@7:
			CMPI.L	#$80000000,D4		; IS IT NAN?
			BNE.S	UNPIGEN 			; IF NOT, MAY BE 0

			MOVEA.W #$7FFF,A4			; SET THE EXPONENT
			MOVEQ	#nancomp,d4 		; SET TO COMP NAN
			SWAP	D4					; ALIGN BYTE
			BSET	#QNANBIT,D4 		; MAKE IT QUIET!							<27MAR85>
			BRA.S	UNPNAN				; AND GO...

UNPIGEN:
			TST.L	D4
			BEQ.S	UNP0				; 0 IS SPECIAL CASE
UNPCGEN:
			BPL.S	@9

			BSET	#7,D6				; SET MINUS SIGN
			NEG.L	D5
			NEGX.L	D4
@9:
			ADDI.W	#$3FFF,D0			; BIAS EXPONENT
			TST.L	D4
			BMI.S	UNPNRM
			BRA.S	UNPCUNR 			; GO NORMALIZE, SANS SIGNAL 		<26MAR85>


;-----------------------------------------------------------
; UNPACK AN EXTENDED: JUST SEPARATE THE SIGN AND LOOK FOR
; CASES.  NOTE THAT THIS CASE MAY FALL THROUGH TO UNPZUN.
;-----------------------------------------------------------
UNPEXT:
			MOVE.W	(A3),D0 			; SIGN AND EXP
			BPL.S	@13

			BSET	#7,D6				; SET SIGN
			BCLR	#15,D0				; CLEAR OPERAND SIGN
@13:
			MOVE.L	2(A3),D4			; LEAD SIG BITS
			MOVE.L	6(A3),D5

			CMPI.W	#$7FFF,D0			; MAX EXP?
			BEQ.S	UNPNIN

			TST.L	D4					; LOOK AT LEAD BITS
			BMI.S	UNPNRM				; NORMALIZED CASE
										; BPL.S FALLS THROUGH

;-----------------------------------------------------------
; HERE DISTINGUISH SPECIAL CASES AND SET BITS IN D2,D3.
;-----------------------------------------------------------
UNPZUN:
			TST.L	D4					; LEAD DIGS = 0?
			BNE.S	UNPUNR
			TST.L	D5
			BNE.S	UNPUNR
UNP0:
			SUBA.L	A4,A4				; EXP <- 0
			ADDQ.W	#2,D3				; MARK AS ZERO
			RTS

;-----------------------------------------------------------
; HI BIT OF D3 USED TO MARK UNNORMAL OPERAND.  WHEN USED AS
; A JUMP TABLE INDEX, D3 IS ACCESSED AS A WORD.
;-----------------------------------------------------------
UNPUNR:
			BSET	#31,D3				; SPECIAL UNNORM FLAG
UNPCUNR:								; ENTRY POINT WHEN INTEGER IN					<26MAR85>
			SUBQ.W	#1,D0				; DECREMENT EXP
			ADD.L	D5,D5
			ADDX.L	D4,D4
			BPL.S	UNPCUNR 			; NEW LABEL TODAY								<26MAR85>

UNPNRM:
			EXT.L	D0
			MOVEA.L D0,A4				; 32-BIT EXP
			RTS
UNPNIN:
			MOVEA.W #$7FFF,A4			; MAX EXP
			BCLR	#31,D4				; IGNORE INT BIT
			TST.L	D4
			BNE.S	UNPNAN
			TST.L	D5
			BNE.S	UNPNAN

			ADDQ.W	#4,D3				; MARK INF
			RTS
;-----------------------------------------------------------
; SET THE SIGNALING BIT (#30).	IF IT WAS CLEAR THEN SIGNAL
; INVALID.
;-----------------------------------------------------------
UNPNAN:
			BSET	#QNANBIT,D4 		; TEST IT, TOO								<26MAR85>
			BNE.S	@1					; IF IT WAS ZERO, SIGNAL!					<26MAR85>
			BSET	#ERRI+8,D6
@1
			ADDQ.W	#2,D2				; JUST A NAN
			RTS



;-----------------------------------------------------------
; UNPACK A SINGLE.	NOTE THAT DENORMS ARE UNPACKED WITHOUT
; THE LEADING BIT, SO EXPONENT MUST BE ADJUSTED.
;-----------------------------------------------------------
UNPSGL:
			CLR.L	D0					; SET UP EXP

			MOVE.L	(A3),D4 			; GET NUMBER
			ADD.B	D6,D6				; UN-ALIGN SIGN WORD
			ADD.L	D4,D4				; SHIFT SIGN OUT OF NUM...
			ROXR.B	#1,D6				; AND INTO SIGN BYTE
			ROL.L	#8,D4				; ALIGN EXPONENT
			MOVE.B	D4,D0				; ISOLATE EXPONENT
			BEQ.S	@21 				; HAVE 0 OR DENORM

			MOVE.B	#1,D4				; CLEAR EXP BITS, THEN
			ROR.L	#1,D4				; PLACE LEADING BIT
			CMPI.B	#$0FF,D0			; MAX EXP?
			BEQ.S	UNPNIN

			ADDI.W	#$3F80,D0			; IT'S NORMALIZED
			BRA.S	UNPNRM
@21:
			MOVE.W	#$3F81,D0			; ASSUME DENORMALIZED
			ROR.L	#1,D4				; ALIGN BITS
			BRA.S	UNPZUN				; AND GO TEST



;-----------------------------------------------------------
; UNPACKING A DOUBLE IS LIKE A SINGLE, BUT HARDER BECAUSE
; OF THE SHIFT REQUIRED FOR ALIGNMENT.
;-----------------------------------------------------------
UNPDBL:
			MOVE.L	(A3),D4 			; HI BITS
			BPL.S	@25

			BSET	#7,D6				; SET SIGN
@25:
			MOVE.L	4(A3),D5			; LO BITS

;-----------------------------------------------------------
; DOUBLE OPERANDS APPEAR AS:  (1) (11) (1 IMPLICIT) (53)
; SO MUST ALIGN BITS LEFT BY 11 AND INSERT LEAD BIT.
; FASTEST BY ROTATE AND MASK.
;-----------------------------------------------------------
			ROL.L	#8,D5				; MUST ALIGN BY 11 BITS
			ROL.L	#3,D5

			ROL.L	#8,D4				; ALIGN EXP AND LEAD DIGS
			ROL.L	#4,D4				; BY 12 TO GET EXP RIGHT
			MOVE.W	D4,D0				; SAVE EXP, WITH EXTRA BITS

			LSR.L	#1,D4				; MAKE WAY FOR LEAD BIT
			ANDI.W	#$0F800,D4			; CLEAR LO 11 BITS
			MOVE.W	D5,D1
			ANDI.W	#$07FF,D1			; GET REPLACEMENTS
			OR.W	D1,D4
			ANDI.W	#$0F800,D5			; CLEAR MOVED BITS

			ANDI.W	#$07FF,D0			; ISOLATE EXP
			BNE.S	@31

			MOVE.W	#$3C01,D0
			BRA 	UNPZUN				; ZERO OR DENORMALIZED ???? WAS BRA.S
@31:
			CMPI.W	#$07FF,D0			; MAX EXP?
			BEQ 	UNPNIN				; ???? WAS BEQ.S

			BSET	#31,D4				; SET LEAD BIT
			ADDI.W	#$3C00,D0			; CORRECT EXP BIAS
			BRA 	UNPNRM				; ???? WAS BRA.S




;-----------------------------------------------------------
;-----------------------------------------------------------
; old FPNANS
;-----------------------------------------------------------
;-----------------------------------------------------------

;-----------------------------------------------------------
; 03JUL82: WRITTEN BY JEROME COONEN
; 10AUG82: HAVE SINGLE JUMP POINT AGAIN. (JTC)
; 28DEC82: DELIVER INTEGER NANS RIGHT HERE, NOT IN CVT (JTC)
; 29APR83: CLASS FUNCTION ADDED, SO NEED A QUICK EXIT FROM
;	NAN HANDLER TO CODE TO RETURN APPROPRIATE VALUE.
;	SLEAZY TRICK: USE HI BIT OF OPCODE 001E TO
;	DISTINGUISH THE TWO INSTRUCTIONS. (JTC)
; 01NOV83: TREAT SIGNAL NAN AS ANY OTHER (JTC).
; 14JAN85: MDS (JTC)
; 26MAR85: CHANGE STATE OF QUIET NAN BIT. (JTC) 							<26MAR85>
;
; NAN HANDLER DEPENDS ON REGISTER MASK: POST-UNPACK.
; ON ENTRY HAVE JUST TST'ED D2, THE NAN CODE REGISTER.
;-----------------------------------------------------------

;-----------------------------------------------------------
; THIS IS TARGET OF ALL INVALID OPERATIONS FOUND DURING
; OPERATIONS.  BITS IN D0 000000XX MUST GO TO 00XX0000.
;-----------------------------------------------------------
INVALIDOP:
			BSET	#ERRI+8,D6
			SWAP	D0					; ALIGN CODE BYTE
			BSET	#QNANBIT,D0 		; MARK IT QUIET 					<26MAR85>
			MOVE.L	D0,D4
			CLR.L	D5					; CLEAR LO HALF
			MOVEA.W #$7FFF,A4			; SET EXPONENT
			BRA.S	NANCOERCE


NANS:
;-----------------------------------------------------------
; ONE NAN: STUFF IT.  TWO NANS: TAKE ONE WITH LARGER
; CODE, OR CONVENIENT (SRC) IF THE CODES ARE =.
; D2: 2-SRC 4-DST 6-BOTH
; MUST NOT DESTROY CODE IN D2.
;-----------------------------------------------------------
QNANS:
			CMPI.W	#2,D2
			BEQ.S	NANSRC
			CMPI.W	#4,D2
			BEQ.S	NANDST

NANPRE:
			MOVE.L	#$00FF0000,D0		; MASK FOR CODE
			MOVE.L	A1,D1				; DST.HI
			AND.L	D0,D1				; DST CODE BYTE
			AND.L	D4,D0				; SRC CODE BYTE
			CMP.L	D0,D1				; DST - SRC
			BLE.S	NANSRC
NANDST:
			ROL.B	#1,D6				; SIGN
			MOVEA.L A3,A4				; EXP
			MOVE.L	A2,D5				; LO DIGS
			MOVE.L	A1,D4				; HI DIGS
NANSRC:


;-----------------------------------------------------------
; BE SURE NAN FITS IN DST, BY CHOPPING TRAILING BITS AND
; STORING "ZERO NAN" IF NECESSARY.
; FIRST, BRANCH OUT ON CMP, INTEGER CASES.	THE TRICK FOR
; INTEGER RESULTS IS TO FORCE THE MAX COMP VALUE
;-----------------------------------------------------------
NANCOERCE:
			BTST	#DSTINT+16,D6		; INTXX OR COMP64 RESULT?
			BEQ.S	NANFLOAT			; FLOATING RESULT...

;-----------------------------------------------------------
; DELIVER A MAXINT IN EACH OF THE 3 INTEGER FORMATS.
; SIGNAL INVALID FOR INT16 AND INT32 NAN RESULTS.
; FOR COMP64, WANT SIGNAL ONLY IF SNAN, BUT ALREADY HAVE
; SIGNAL FROM ABOVE SO DIFFERENCE IS IRRELEVANT HERE.
; FORMAT CODES:  4-INT16  5-INT32  6-COMP64  IN D6.HI.
; VALUES: INT16 -- 00000000 00008000
;	  INT32 -- 00000000 80000000
;	  COMP	-- 80000000 00000000
;-----------------------------------------------------------
			CLR.L	D4					; 0 --> D4
			MOVEQ	#1,D5				; $80000000 --> D5
			ROR.L	#1,D5

			BTST	#DSTLO+16,D6		; BB1 --> INT32
			BNE.S	@21
			BTST	#DSTMD+16,D6		; B10 --> COMP64
			BNE.S	@41

			SWAP	D5
@21:
			BSET	#ERRI+8,D6
			RTS
@41:
			EXG 	D4,D5
			RTS


;-----------------------------------------------------------
; THE NON-INTEGER OPERATIONS ARE OF TWO TYPES: THOSE THAT
; HAVE A FLOATING RESULT (THE USUAL) AND THOSE THAT DO NOT
; (COMPARE AND CLASS).	DISTINGUISH THE LATTER ACCORDING TO
; THE HI OPCODE BIT.  (0 FOR CMP, 1 FOR CLASS).
;-----------------------------------------------------------
NANFLOAT:
			BTST	#DSTOUT+16,D6		; IS IT A CMP OR CLASS?
			BNE.S	FPNANOUT

;-----------------------------------------------------------
;
;-----------------------------------------------------------
			BTST	#OPHIBIT+16,D6		; 0 = CMP
			BNE.S	@5
			MOVEQ	#CMPU,D0			; MARK UNORERED
			BRA 	CMPFIN
@5:
			MOVEQ	#1,D0				; SNAN = 1, QNAN = 2
			BCLR	#ERRI+8,D6			; INVALID SET -> SNAN
			BNE.S	@7

			ADDQ.W	#1,D0
@7:
			BRA 	CLASSFIN

FPNANOUT:
			BTST	#SPREC+16,D6		; CHECK FOR SINGLE
			BEQ.S	@1

			MOVEQ	#0,D5
			MOVE.B	D5,D4
			BRA.S	@2
@1:
			BTST	#DPREC+16,D6		; CHECK FOR DOUBLE
			BEQ.S	@2

			ANDI.W	#$0F800,D5

;-----------------------------------------------------------
; CLEAR QUIET BIT AND CHECK FOR ANY OTHERS NONZERO...
;-----------------------------------------------------------
@2:
			MOVE.L	D4,D0				; CHECK FOR ALL 0
			BCLR	#QNANBIT,D0 		; ...EXCEPT QNANBIT 					<26MAR85>
			OR.L	D5,D0
			BNE.S	@3

			MOVEQ	#nanzero,D4 		; SPECIAL NAN
			SWAP	D4
			BSET	#QNANBIT,D4 		; MARK IT QUIET!						<26MAR85>
@3:
			RTS




;-----------------------------------------------------------
;-----------------------------------------------------------
; old FPCOERCE
;-----------------------------------------------------------
;-----------------------------------------------------------

;-----------------------------------------------------------
; 03JUL82: WRITTEN BY JEROME COONEN
; 11AUG82: CLEANUP
; 01SEP82: RND MODE ENCODING CHANGED (JTC)
; 12DEC82: UFLOW DEFINITION CHANGED TO SUPPRESS SIGNAL WHEN
;	RESULT IS EXACT, EVEN IF TINY (JTC)
; 13APR83: COMMENT OUT THE TRAP BYPASS CODES FOR OVERFLOW
;	AND UNDERFLOW, SO DEFAULT RESULT IS ALWAYS DELIVERED.
;							(JTC)
; 4APR84: FIXED BUG IN DCOERCE (JTC)
; 14JAN85: MDS (JTC)
;
; FOR LACK OF A BETTER PLACE, THESE FIRST UTILITIES ARE
; STUCK WITH THE COERCION ROUTINES.
;-----------------------------------------------------------

;-----------------------------------------------------------
; THESE ROUTINES HANDLE THE SPECIAL CASES IN OPERATIONS
; WHEN ONE OR THE OTHER OF THE OPERANDS IS THE RESULT.
; SUBCASES DEPEND ON WHETHER THE SIGN SHOULD BE
; STUFFED TOO.	THE SRC-IS-RES IS ALWAYS TRIVIAL.
;-----------------------------------------------------------
RDSTSGN:
			ADD.B	D6,D6				; SHIFT DST SIGN TO BIT #7
RDST:
			MOVE.L	A1,D4
			MOVE.L	A2,D5
			MOVEA.L A3,A4				; EXP TOO
RSRCSGN:
RSRC:
			RTS


;-----------------------------------------------------------
; RTSHIFT MILESTONE ++++++++++++++++++++++++++++++++++++++ .
;
; THIS IS THE RIGHT SHIFTER USED IN ADD/SUB, DENORM,...
; VARIANT SKIPS CHECK FOR SUPERFLUOUS SHIFTS OVER 66.
;-----------------------------------------------------------

RTSHIFT:
			CMPI.W	#66,D0
			BLS.S	QRTSHIFT
			MOVE.W	#66,D0
QRTSHIFT:
			LSR.L	#1,D4				; SHIFT 0 IN
			ROXR.L	#1,D5
			ROXR.W	#1,D7
			SCS 	D1					; SAVE C-OUT
			OR.B	D1,D7
			SUBQ.W	#1,D0
			BNE.S	QRTSHIFT
			RTS


;-----------------------------------------------------------
; ASSUME POST-OPERATION REGISTER MASK, WITH RESULT IN
; D7.B, A4, D4,5.  COERCE ACCORDING TO BITS IN D6.W.
;
; USUALLY ASSUME OPERAND IS A NONZERO, FINITE NUMBER.
; VARIANTS WILL NORMALIZE THE NUMBER, EVEN CHECKING
; IT FOR ZERO FIRST.
;-----------------------------------------------------------

;-----------------------------------------------------------
; CHECK VALUE FIRST, EXIT IF ZER0, WITH EXP FIX.
;-----------------------------------------------------------
ZNORMCOERCE:
			TST.L	D4
			BNE.S	NORMCOERCE
			TST.L	D5
			BNE.S	NORMCOERCE
			TST.W	D7					; MAY BE JUST ROUND BITS
			BNE.S	NORMCOERCE

			SUBA.L	A4,A4				; SET EXP TO 0
			RTS 						; NEVER COERCE 0

;-----------------------------------------------------------
; ASSUME, AS AFTER SUBTRACT THAT VALUE IS NONZERO.	USE 1ST
; BRANCH TO SHORTEN ACTUAL LOOP BY A BRANCH.
;-----------------------------------------------------------
NORMCOERCE:
			TST.L	D4					; CHECK FOR LEAD 1
			BRA.S	@2
@1:
			SUBQ.L	#1,A4				; DECREMENT EXP
			ADD.W	D7,D7				; SHIFT RND
			ADDX.L	D5,D5				; LO BITS
			ADDX.L	D4,D4
@2:
			BPL.S	@1					; WHEN NORM, FALL THROUGH

;-----------------------------------------------------------
; COERCE MILESTONE +++++++++++++++++++++++++++++++++++++++ .
;
; RUN SEPARATE SEQUENCES FOR EXT, SGL, DBL TO SAVE TESTS.
; NOTE THAT FOR CONVENIENCE IN BRANCHING, THE SGL AND DBL
; COERCE SEQUENCES FOLLOW THE COERCE ROUTINES.
; SINCE OVERFLOW RESULTS IN A VALUE DEPENDING ON THE
; PRECISION CONTROL BITS, RETURN CCR KEY FROM OFLOW:
; EQ: OK  NE: HUGE
;-----------------------------------------------------------
COERCE:
			TST.L	D6					; CHEAP SUBST FOR #SPREC+16
			BMI 	SCOERCE
			BTST	#DPREC+16,D6		; IS IT DOUBLE
			BNE 	DCOERCE

			SUBA.L	A3,A3				; EXT UFLOW THRESH
			BSR.S	UFLOW

			CLR.L	D1					; SET INCREMENT FOR RND
			MOVEQ	#1,D2
			BTST	#0,D5				; LSB = 1?
			BSR.S	ROUND

			MOVEA.W #$7FFE,A3			; OFLOW THRESH
			BSR.S	OFLOW
			BEQ.S	@1

;-----------------------------------------------------------
; STORE EXTENDED HUGE -- JUST A STRING OF 1'S.
;-----------------------------------------------------------
			MOVEA.L A3,A4				; MAX FINITE EXP
			MOVEQ	#-1,D4
			MOVE.L	D4,D5
@1:
			RTS



;-----------------------------------------------------------
; UFLOW MILESTONE ++++++++++++++++++++++++++++++++++++++++ .
;
; UNDERFLOW TEST -- DENORMALIZED REGARDLESS
;-----------------------------------------------------------
UFLOW:
			MOVE.L	A3,D0				; COPY THRESHOLD
			SUB.L	A4,D0				; THRESH - EXP
			BGT.S	@1
			RTS
@1:
			BSET	#ERRU+8,D6			; SIGNAL UNDERFLOW

;-----------------------------------------------------------
******** DELETED - NO IEEE TRAP SUPPORT
;	 BTST	 #ERRU,1(A0)	 ; TRAP BITS IN STATE.LO
;	 BEQ.S	 @3
;	 RTS
;@3:
;-----------------------------------------------------------

			MOVEA.L A3,A4				; EXP <- THRESH
			BRA.S	RTSHIFT



;-----------------------------------------------------------
; ROUND MILESTONE ++++++++++++++++++++++++++++++++++++++++ .
;
; ROUND BASED ON GUARD AND STICKY IN D7.W AND LSB WHOSE
; COMPLEMENT IS IN THE Z FLAG THANKS TO A BTST.
; SUPPRESS UFLOW FLAG IF EXACT AND NONTRAPPING.
;-----------------------------------------------------------
ROUND:;-----------------------------------------------------------

			SNE 	D0					; RECORD LSB

			TST.W	D7					; ANY NONZERO BITS?
			BNE.S	@1


;-----------------------------------------------------------
; IF NOT TRAPPING ON UFLOW, JUST SUPPRESS ANY UFLOW SIGNAL.
; SINCE WE DON'T SUPPORT TRAPPING, ALWAYS SUPPRESS SIGNAL.
;-----------------------------------------------------------
;
;	 BTST	 #ERRU,1(A0)	 ; TRAPPING <-- 1
;	 BNE.S	 @101
;-----------------------------------------------------------

			BCLR	#ERRU+8,D6			; SUPPRESS UFLOW SIGNAL

;-----------------------------------------------------------
;@101:
;-----------------------------------------------------------
			RTS

@1:
			BSET	#ERRX+8,D6			; SIGNAL INEXACT
			BTST	#RNDLO,(A0) 		; NEAREST & TOWARD -INF: X0
			BEQ.S	@5					; LOOKING FOR 00 AND 10
			BTST	#RNDHI,(A0) 		; CHOP: 11 TOWARD +INF: 01
			BEQ.S	@3
			RTS
@3:
			TST.B	D6					; PLUS?
			BPL.S	ROUNDUP
			RTS
@5:
			BTST	#RNDHI,(A0) 		; NEAR: 00	TOWARD -INF: 10
			BNE.S	@7

			CMPI.W	#$8000,D7			; 1/2 CASE?
			BCC.S	@51
			RTS 						; < 1/2
@51:
			BHI.S	ROUNDUP
			TST.B	D0					; CHECK LSB
			BNE.S	ROUNDUP
			RTS
@7:
			TST.B	D6					; MINUS?
			BMI.S	ROUNDUP
			RTS

;-----------------------------------------------------------
; RECORD INCREMENT OF SIGNIFICAND.
;-----------------------------------------------------------
ROUNDUP:
			BSET	#RNDINC,1(A0)

			ADD.L	D2,D5
			ADDX.L	D1,D4
			BCC.S	@9

			ROXR.L	#1,D4
			ADDQ.L	#1,A4
@9:
			RTS


;-----------------------------------------------------------
; OFLOW MILESTONE ++++++++++++++++++++++++++++++++++++++++ .
;
; CHECK FOR OVERFLOW WITH THRESH IN A3, IF SO, STUFF INF
; AND RETURN WITH CCR AS NE IF HUGE SHOULD BE STUFFED.
;-----------------------------------------------------------
OFLOW:
			CMPA.L	A4,A3
			BLT.S	@1
			CLR.W	D0					; SET EQ
			RTS
@1:
			BSET	#ERRO+8,D6			; SET FLAG REGARDLESS

;-----------------------------------------------------------
; REMOVE TRAP CODE TO BYPASS DEFAULT RESULT ON TRAP
;
;	 BTST	 #ERRO,1(A0)	 ; CHECK FOR TRAP
;	 BEQ.S	 @10
;
;	 CLR.W	 D0 	 ; SET EQ
;	 RTS
;@10:
;-----------------------------------------------------------

			BSET	#ERRX+8,D6			; INEXACT, TOO

;-----------------------------------------------------------
; STORE INF WITH SIGN OF OVERFLOWED VALUE, THEN CHECK...
;-----------------------------------------------------------
			MOVEA.W #$7FFF,A4			; MAX EXP
			CLR.L	D4					; MAKE INF
			MOVE.L	D4,D5

;-----------------------------------------------------------
; SINCE NONTRAPPING, RESULT IS EITHER 'INF' OR 'HUGE'.
; HAVE 'INF' ALREADY; RETURN WITH CCR SET TO 'NE' IF
; 'HUGE' IS NEEDED.
;
; RETURN WITH EQ IFF NEAR, (+ & RNDUP), OR (- & RNDDN).
;-----------------------------------------------------------
			MOVE.B	(A0),D1
			AND.B	#RNDMSK,D1
			BNE.S	@2					; ASSUME 00-NEAR
			RTS 						; RETURN WITH INF
@2:
;-----------------------------------------------------------
; NOW USE TRICK TO RETURN WITH CCR SET JUST RIGHT.
;-----------------------------------------------------------
			CMPI.B	#RND0,D1			; CHOPPING?
			BNE.S	@4
			TST.B	D1					; TO SET NE -- ALWAYS HUGE
			RTS
@4:
			TST.B	D6					; CHECK SIGN
			BMI.S	@5

			CMPI.B	#RNDUP,D1			; MUST BE EQ TO KEEP INF
			RTS
@5:
			CMPI.B	#RNDDN,D1			; MUST BE EQ TO KEEP INF
			RTS



;-----------------------------------------------------------
; THE SINGLE AND DOUBLE COERCE ROUTINES WERE PLACE DOWN
; HERE SO THEY COULD ACCESS THE UTILITIES WITH SHORT BR'S.
;-----------------------------------------------------------
SCOERCE:
			MOVEA.W #$3F81,A3			; SGL UFLOW THRESH
			BSR 	UFLOW				; ???? WAS BSR.S

			TST.L	D5					; ANY LO BITS?
			SNE 	D0
			OR.B	D0,D7				; SAVE AS STICKIES
			ADD.B	D4,D4				; GUARD TO X
			ROXR.W	#1,D7				; X TO GUARD
			OR.B	D4,D7				; LAST STICKIES

			CLR.L	D5					; CLEAR LO BITS
			CLR.B	D4

			MOVE.L	#$0100,D1			; SET INCREMENT FOR RND
			CLR.L	D2

			BTST	#8,D4				; LSB -> Z
			BSR 	ROUND				; WAS BSR.S

			MOVEA.W #$407E,A3			; OFLOW THRESH
			BSR.S	OFLOW
			BEQ.S	@3

;-----------------------------------------------------------
; STORE SINGLE HUGE -- 24 ONES WITH BIASED 7F EXP.
;-----------------------------------------------------------
			MOVEA.L A3,A4				; MAX SGL EXP
			MOVEQ	#-1,D4
			CLR.B	D4
@3:
			RTS


DCOERCE:
			MOVEA.W #$3C01,A3			; DBL UFLOW THRESH
			BSR 	UFLOW				; WAS BSR.S

			MOVE.W	#$07FF,D0			; MASK FOR LOW BITS
			AND.W	D5,D0
			ANDI.W	#$0F800,D5			; CLEAR LO BITS
			LSL.W	#5,D0				; LEFT ALIGN
			LSR.W	#1,D7				; MAKE WAY FOR GUARD
			BCC.S	@1					; RECORD POSSIBLE STRAY STICKY BIT
			BSET	#0,D7
@1:
			OR.W	D0,D7

			CLR.L	D1					; SET INCREMENT FOR RND
			MOVE.L	#$00000800,D2

			BTST	#11,D5				; LSB -> Z
			BSR 	ROUND				; WAS BSR.S

			MOVEA.W #$43FE,A3			; OFLOW THRESH
			BSR 	OFLOW				; WAS BSR.S
			BEQ.S	@5

;-----------------------------------------------------------
; STORE DOUBLE HUGE -- 53 ONES WITH BIASED 3FF EXP.
;-----------------------------------------------------------
			MOVEA.L A3,A4
			MOVEQ	#-1,D4				; LEAD 32 BITS
			MOVE.L	#$FFFFF800,D5		; FINAL 21 BITS
@5:
			RTS




;-----------------------------------------------------------
;-----------------------------------------------------------
; old FPPACK
;-----------------------------------------------------------
;-----------------------------------------------------------

;-----------------------------------------------------------
; 03JUL82: WRITTEN BY JEROME COONEN
; 14JAN85: MDS (JTC)
;
; ASSUME REGISTER MASK: POST COERCE, WITH DIRTY INDEX IN D0
; HAVE RESULT SIGN IN D7, EXP IN A4, DIGS IN D4,5
; CRUCIAL THAT EXTRANEOUS SIGNIFICANT BITS BE CLEAR.
; USE D3 FOR EXP COMPUTATIONS.
;-----------------------------------------------------------

PACK:
			ANDI.W	#$000E,D0			; KILL EXTRANEOUS BITS

			IF		 PCOK THEN
			MOVE.W	PACKCASE(PC,D0),D0
			ELSE
			MOVE.W	PACKCASE(D0),D0
			ENDIF

			MOVEA.L LKADR1(A6),A3		; LOAD DST ADRS

;-----------------------------------------------------------
; USE TRICK TO SPARE SEVERAL COMPARISONS.
;-----------------------------------------------------------
			MOVE.W	A4,D3				; GET EXP
			CMPI.W	#$7FFF,D3			; INF OR NAN?

			IF		 PCOK THEN
			JMP 	PACK(PC,D0)
			ELSE
			JMP 	PACK(D0)
			ENDIF

PACKCASE:
			DC.W	 PACKEXT-PACK
			DC.W	 PACKDBL-PACK
			DC.W	 PACKSGL-PACK
			DC.W	 0
			DC.W	 PACKI16-PACK
			DC.W	 PACKI32-PACK
			DC.W	 PACKC64-PACK

;-----------------------------------------------------------
; INT16: JUST STORE.
;-----------------------------------------------------------
PACKI16:
			MOVE.W	D5,(A3)
			RTS


;-----------------------------------------------------------
; INT32: CHECK FOR MAX EXP TO STORE MAX NEG INT, WHILE
;	SIGNALING INVALID.
;-----------------------------------------------------------
PACKI32:
			MOVE.L	D5,(A3)
			RTS

;-----------------------------------------------------------
; COMP64: CHECK FOR NAN CASE, BUT NO SIGNAL.
;-----------------------------------------------------------
PACKC64:
			MOVE.L	D4,(A3)+
			MOVE.L	D5,(A3)
			RTS


;-----------------------------------------------------------
; NOT SO EASY TO PACK AN EXTENDED.	JUST STUFF THE SIGN;
; BUT BE SURE TO NORMALIZE UNDERFLOWED S,D DENORMALS.
;-----------------------------------------------------------
PACKEXT:
			BTST	#ERRU+8,D6			; UNDERFLOW
			BEQ.S	@7					; OK IF NO UFLOW

			TST.W	D3					; MIN EXP?
			BEQ.S	@7					; IF 0, NO PROBLEM

			TST.L	D4					; NORMALIZED OR NONZERO?
			BNE.S	@5

			TST.L	D5					; IF ZERO THEN FORCE 0
			BNE.S	@1					; UNNORM BY > 32 BITS!

			CLR.L	D3					; FORCE ZERO EXP
			BRA.S	@7
@1:
			SUBQ.W	#1,D3				; DEC EXP
			ADD.L	D5,D5
			ADDX.L	D4,D4
@5:
			BPL.S	@1					; PLS -> UNNORM
@7:
			TST.B	D6					; NEGATIVE?
			BPL.S	@11
			ADDI.W	#$8000,D3			; STUFF NEG SIGN
@11:
			MOVE.W	D3,(A3)+
			MOVE.L	D4,(A3)+
			MOVE.L	D5,(A3)
			RTS


;-----------------------------------------------------------
; PACK SINGLE: IF INF OR NAN PLACE TOO BIG EXP AND COUNT
; ON LEAD BIT=0 TO FORCE EXP DECREMENT.
;-----------------------------------------------------------
PACKSGL:
			BNE.S	@1					; NE -> INF OR NAN
			MOVE.W	#$4080,D3			; EXP TOO BIG, WILL DEC
			BRA.S	@5
@1:
			TST.W	D3					; EXP = 0?
			BNE.S	@5
			MOVE.W	#$3F81,D3
@5:
			SUBI.W	#$3F80,D3
			ADD.L	D4,D4				; KILL LEAD BIT AND TEST
			BCS.S	@7					; DEC EXP UNLESS NORMAL
			SUBQ.W	#1,D3
@7:
			OR.W	D3,D4				; STUFF EXP IN LOW BITS
			ROR.L	#8,D4
			ADD.B	D6,D6				; GET SIGN INTO X
			ROXR.L	#1,D4				; SHOVE SIGN
			MOVE.L	D4,(A3)
			RTS


;-----------------------------------------------------------
; PACK DOUBLE:
;-----------------------------------------------------------
PACKDBL:
			BNE.S	@1					; NE -> INF OR NAN
			MOVE.W	#$4400,D3			; EXP TOO BIG, WILL DEC
			BRA.S	@5
@1:
			TST.W	D3					; EXP = 0?
			BNE.S	@5
			MOVE.W	#$3C01,D3
@5:
			SUBI.W	#$3C00,D3
			TST.L	D4					; KILL LEAD BIT AND TEST
			BMI.S	@7					; DEC EXP UNLESS NORMAL
			SUBQ.W	#1,D3
@7:

;-----------------------------------------------------------
; SET UP LOW 32 BITS WITH TRAILING 11 BITS FROM HI BITS.
;-----------------------------------------------------------
			MOVE.L	#$000007FF,D0		; MASK HI BITS OF 2ND HALF
			AND.L	D4,D0
			OR.L	D0,D5
			ROR.L	#8,D5
			ROR.L	#3,D5				; NOW LO 32 BITS READY

			ANDI.W	#$0F800,D4			; CLEAR LO BITS JUST USED
			ADD.L	D4,D4				; KILL LEAD BIT
			OR.W	D3,D4				; PLACE EXP
			ROR.L	#8,D4
			ROR.L	#3,D4
			ADD.B	D6,D6				; SIGN TO X
			ROXR.L	#1,D4

			MOVE.L	D4,(A3)+
			MOVE.L	D5,(A3)
			RTS