misc/060tsys/t29float.s
;----------------------------------------------------------------
;
;	FEファンクション
;
;----------------------------------------------------------------

	.include	t02const.equ
	.include	t06float.equ

	.cpu	68060

;----------------------------------------------------------------
;未完成のルーチン
;	_USING	_FUSING	(#INFと#NANの処理)
;	_POWER	_FPOWER
;	_DTOS	(pi()/180などの指数部の表示)


;----------------------------------------------------------------
;FPUが処理する浮動小数点命令
;	FABS	FADD	FBcc	FCMP	FDABS	FDADD	FDDIV	FDIV
;	FDMOVE	FDMUL	FDNEG	FDSQRT	FDSUB	FINT	FINTRZ	FMOVE
;	FMOVEM*	FMUL	FNEG	FNOP	FRESTORE	FSABS	FSADD
;	FSDIV	FSMOVE	FSMUL	FSNEG	FSAVE	FSQRT	FSSQRT	FSSUB
;	FSUB	FTST

;----------------------------------------------------------------
;FPSPが処理する浮動小数点命令
;	FACOS	FASIN	FATAN	FATANH	FCOS	FCOSH	FDBcc	FETOX
;	FETOXM1	FGETEXP	FGETMAN	FLOG10	FLOG2	FLOGN	FLOGNP1	FMOD
;	FMOVECR	FMOVEM*	FREM	FSCALE	FScc	FSGLDIV	FSGLMUL	FSIN
;	FSINCOS	FSINH	FTAN	FTANH	FTENTOX	FTRAPcc	FTWOTOX

;----------------------------------------------------------------
;FPSP内部のエミュレーションルーチンのオフセット
acos	reg	sacos			;_060FPSP_TABLE+$00003D42
asin	reg	sasin			;_060FPSP_TABLE+$00003C8E
atan	reg	satan			;_060FPSP_TABLE+$00003A4A
atanh	reg	satanh			;_060FPSP_TABLE+$000056B2
cos	reg	scos			;_060FPSP_TABLE+$00002404
cosh	reg	scosh			;_060FPSP_TABLE+$00004778
etox	reg	setox			;_060FPSP_TABLE+$00004272
etoxm1	reg	setoxm1			;_060FPSP_TABLE+$00004442
getexp	reg	sgetexp			;_060FPSP_TABLE+$000046FE
getman	reg	sgetman			;_060FPSP_TABLE+$00004732
log10	reg	slog10			;_060FPSP_TABLE+$0000575A
log2	reg	slog2			;_060FPSP_TABLE+$000057AA
logn	reg	slogn			;_060FPSP_TABLE+$00005318
lognp1	reg	slognp1			;_060FPSP_TABLE+$00005558
mod	reg	smod_snorm		;_060FPSP_TABLE+$00006C36
rem	reg	srem_snorm		;_060FPSP_TABLE+$00006D3E
scale	reg	sscale_snorm		;_060FPSP_TABLE+$00006DE0
sin	reg	ssin			;_060FPSP_TABLE+$000023FA
sincos	reg	ssincos			;_060FPSP_TABLE+$000025F2
sinh	reg	ssinh			;_060FPSP_TABLE+$00004836
tan	reg	stan			;_060FPSP_TABLE+$00002EBC
tanh	reg	stanh			;_060FPSP_TABLE+$0000491A
tentox	reg	stentox			;_060FPSP_TABLE+$00005D8C
twotox	reg	stwotox			;_060FPSP_TABLE+$00005C94

;----------------------------------------------------------------
;
;	fpsp	関数名
;
;	機能
;		・FPSP内部のエミュレーションルーチンを呼び出します。
;
;	引数
;		FP0	関数の引数
;
;	返却値
;		FP0	演算結果
;		D7	FPSR
;
;	破壊レジスタ
;		D0-D1
;
;----------------------------------------------------------------
fpsp	.macro	name
	move.l	a1,-(sp)
		move.l	a0,-(sp)
	link	a6,#-192
	clr.l	-192+32(a6)		;FPCR
		clr.l	-192+36(a6)		;FPSR
	fmove.x	fp0,-(sp)
	movea.l	sp,a0
		moveq.l	#0,d0			;ラウンディングモード
	jsr	name

	move.l	-192+36(a6),d7		;FPSR
;;;	lea.l	12(sp),sp
	unlk	a6
	movea.l	(sp)+,a0
		movea.l	(sp)+,a1
	.endm

;----------------------------------------------------------------
;
;	exit	引数,…
;
;	機能
;		・F系列命令エミュレーションを終了します。
;		・復元するレジスタ、CCRの設定、スタックに出力するデータなどを
;		  指定できます。
;
;	引数(復元するレジスタに関するもの)
;		・d0~d6 のレジスタ名を複数指定できます。
;		・アドレスレジスタは指定できません。
;			dn	dnを復元します。
;				dは小文字で、nは0~6の数字です。
;
;	引数(CCRに関するもの)
;		・CCRに関する引数の指定がなければ、CCRは変化しません。
;		  (FEファンクションコールの前後で変化しません)
;		・_,C,V,Z,N,Xの6つに限り、複数指定できます。
;		・_,C,V,Z,N,Xのいずれかが指定されているときは、指定されなかったフラグは
;		  クリアされます。
;			_	すべてのフラグをクリアします。
;			C	Cフラグをセットします。
;			V	Vフラグをセットします。
;			Z	Zフラグをセットします。
;			N	Nフラグをセットします。
;			X	Xフラグをセットします。
;			ccr	現在のccrの内容をそのまま返します。
;			Dn	現在のDnの内容をccrに設定します。
;				Dは大文字で、nは0~7の数字です。
;
;	引数(スタックに出力するデータに関するもの)
;		・次のいずれか1つを指定できます。
;		・デクリメントモードとは、既に1ロングワード分インクリメントされている
;		  場合です。
;			=n	dnを出力します。
;			=mn	dm/dnを出力します。
;			-n	dnを出力します。(デクリメントモード)
;			-mn	dm/dnを出力します。(デクリメントモード)
;				m,nは0~7の数字です。
;
;	補足
;		・引数の順序は任意です。
;		・引数がおかしいと、アセンブル時にエラーになります。
;
;----------------------------------------------------------------
exit	.macro	_0,_1,_2,_3,_4,_5,_6,_7,_8,_9
	.local	REGCNT,REGLST,F_IMM,F_REG,F_CCR,IMM_CC,REG_CC,CODE
	.local	x
	.local	trace
REGCNT	=	2	;復元するレジスタの個数
REGLST	reg	d7/a6	;復元するレジスタのレジスタリスト
F_IMM	=	0	;CCRをイミディエイトで返すとき1
F_REG	=	0	;CCRをレジスタで返すとき1
F_CCR	=	0	;CCRをそのまま返すとき1
IMM_CC	=	0	;CCRに設定するイミディエイトの値
REG_CC	reg	d7	;CCRに設定するレジスタ(CCRをそのまま返すときはd7)
CODE	=	0	;スタックにデータを出力するオペコード
  .irp %p,_9,_8,_7,_6,_5,_4,_3,_2,_1,_0
    .if ' &%p'>' '
x	=	'&%p'
      .if x>>8='d'
REGCNT	=	REGCNT+1
REGLST	reg	%p/REGLST
      .elseif x='_'
F_IMM	=	1
      .elseif x='C'|x='V'|x='Z'|x='N'|x='X'
F_IMM	=	1
IMM_CC	=	IMM_CC|%p
      .elseif x>>8='D'
F_REG	=	1
REG_CC	reg	%p
      .elseif x='ccr'
F_CCR	=	1
      .elseif x>>8='='
CODE	=	$2C80+x.mod.8		;move.l dn,(a6)
      .elseif x>>8='-'
CODE	=	$2D00+x.mod.8		;move.l dn,-(a6)
      .elseif x>>16='='
CODE	=	$10000*($2CC0+(.high.x).mod.8)+($2C80+(.low.x).mod.8)
					;move.l dm,(a6)+
					;move.l dn,(a6)
      .elseif x>>16='-'
CODE	=	$10000*($2C80+(.low.x).mod.8)+($2D00+(.low.x).mod.8)
					;move.l dn,(a6)
					;move.l dm,-(a6)
      .else
	.fail	1	;exitマクロの引数がおかしい
      .endif
    .endif
  .endm
  .if F_CCR
    .fail CODE.mod.8=7|(CODE>>16).mod.8=7
	move.w	ccr,REG_CC
  .endif
  .if CODE>>16
	.dc.l	CODE
  .elseif CODE
	.dc.w	CODE
  .endif
  .if F_IMM
    .if IMM_CC
	move.b	#IMM_CC,4*REGCNT+1(sp)
    .else
	clr.b	4*REGCNT+1(sp)
    .endif
  .elseif F_REG|F_CCR
	move.b	REG_CC,4*REGCNT+1(sp)
  .endif
	movem.l	(sp)+,REGLST
	tst.w	(sp)
	bmi	trace
	rte

trace:
	ori.w	#$8000,sr
	rte
	.endm

;----------------------------------------------------------------
;
;	param	areg
;
;	機能
;		・スタックのパラメータのアドレスを求めます。
;
;	引数
;		areg	アドレスレジスタ
;
;	補足
;		各FEファンクションコールに分岐した直後で指定して下さい。
;		SPが変化していると正常に機能しません。
;		そのため、実質的にアドレスレジスタはA6のみ指定可能です。
;
;----------------------------------------------------------------
param	.macro	areg
	.local	super
	btst.b	#5,4*2+0(sp)
		lea.l	4*2+8(sp),areg
	bne	super
	move.l	usp,areg
super:
	.endm

;----------------------------------------------------------------

	.text

;----------------------------------------------------------------
;FEファンクションコールジャンプテーブル
feJumpTable::
	.dc.l	fe_lmul		;$FE00
	.dc.l	fe_ldiv		;$FE01
	.dc.l	fe_lmod		;$FE02
	.dc.l	fe_undefined	;$FE03
	.dc.l	fe_umul		;$FE04
	.dc.l	fe_udiv		;$FE05
	.dc.l	fe_umod		;$FE06
	.dc.l	fe_undefined	;$FE07
	.dc.l	fe_imul		;$FE08
	.dc.l	fe_idiv		;$FE09
	.dc.l	fe_undefined	;$FE0A
	.dc.l	fe_undefined	;$FE0B
	.dc.l	fe_randomize	;$FE0C
	.dc.l	fe_srand	;$FE0D
	.dc.l	fe_rand		;$FE0E
	.dc.l	fe_undefined	;$FE0F
	.dc.l	fe_stol		;$FE10
	.dc.l	fe_ltos		;$FE11
	.dc.l	fe_stoh		;$FE12
	.dc.l	fe_htos		;$FE13
	.dc.l	fe_stoo		;$FE14
	.dc.l	fe_otos		;$FE15
	.dc.l	fe_stob		;$FE16
	.dc.l	fe_btos		;$FE17
	.dc.l	fe_iusing	;$FE18
	.dc.l	fe_undefined	;$FE19
	.dc.l	fe_ltod		;$FE1A
	.dc.l	fe_dtol		;$FE1B
	.dc.l	fe_ltof		;$FE1C
	.dc.l	fe_ftol		;$FE1D
	.dc.l	fe_ftod		;$FE1E
	.dc.l	fe_dtof		;$FE1F
	.dc.l	fe_val		;$FE20
	.dc.l	fe_using	;$FE21
	.dc.l	fe_stod		;$FE22
	.dc.l	fe_dtos		;$FE23
	.dc.l	fe_ecvt		;$FE24
	.dc.l	fe_fcvt		;$FE25
	.dc.l	fe_gcvt		;$FE26
	.dc.l	fe_undefined	;$FE27
	.dc.l	fe_dtst		;$FE28
	.dc.l	fe_dcmp		;$FE29
	.dc.l	fe_dneg		;$FE2A
	.dc.l	fe_dadd		;$FE2B
	.dc.l	fe_dsub		;$FE2C
	.dc.l	fe_dmul		;$FE2D
	.dc.l	fe_ddiv		;$FE2E
	.dc.l	fe_dmod		;$FE2F
	.dc.l	fe_dabs		;$FE30
	.dc.l	fe_dceil	;$FE31
	.dc.l	fe_dfix		;$FE32
	.dc.l	fe_dfloor	;$FE33
	.dc.l	fe_dfrac	;$FE34
	.dc.l	fe_dsgn		;$FE35
	.dc.l	fe_sin		;$FE36
	.dc.l	fe_cos		;$FE37
	.dc.l	fe_tan		;$FE38
	.dc.l	fe_atan		;$FE39
	.dc.l	fe_log		;$FE3A
	.dc.l	fe_exp		;$FE3B
	.dc.l	fe_sqr		;$FE3C
	.dc.l	fe_pi		;$FE3D
	.dc.l	fe_npi		;$FE3E
	.dc.l	fe_power	;$FE3F
	.dc.l	fe_rnd		;$FE40
	.dc.l	fe_sinh		;$FE41
	.dc.l	fe_cosh		;$FE42
	.dc.l	fe_tanh		;$FE43
	.dc.l	fe_atanh	;$FE44
	.dc.l	fe_asin		;$FE45
	.dc.l	fe_acos		;$FE46
	.dc.l	fe_log10	;$FE47
	.dc.l	fe_log2		;$FE48
	.dc.l	fe_dfrexp	;$FE49
	.dc.l	fe_dldexp	;$FE4A
	.dc.l	fe_daddone	;$FE4B
	.dc.l	fe_dsubone	;$FE4C
	.dc.l	fe_ddivtwo	;$FE4D
	.dc.l	fe_dieecnv	;$FE4E
	.dc.l	fe_ieedcnv	;$FE4F
	.dc.l	fe_fval		;$FE50
	.dc.l	fe_fusing	;$FE51
	.dc.l	fe_stof		;$FE52
	.dc.l	fe_ftos		;$FE53
	.dc.l	fe_fecvt	;$FE54
	.dc.l	fe_ffcvt	;$FE55
	.dc.l	fe_fgcvt	;$FE56
	.dc.l	fe_undefined	;$FE57
	.dc.l	fe_ftst		;$FE58
	.dc.l	fe_fcmp		;$FE59
	.dc.l	fe_fneg		;$FE5A
	.dc.l	fe_fadd		;$FE5B
	.dc.l	fe_fsub		;$FE5C
	.dc.l	fe_fmul		;$FE5D
	.dc.l	fe_fdiv		;$FE5E
	.dc.l	fe_fmod		;$FE5F
	.dc.l	fe_fabs		;$FE60
	.dc.l	fe_fceil	;$FE61
	.dc.l	fe_ffix		;$FE62
	.dc.l	fe_ffloor	;$FE63
	.dc.l	fe_ffrac	;$FE64
	.dc.l	fe_fsgn		;$FE65
	.dc.l	fe_fsin		;$FE66
	.dc.l	fe_fcos		;$FE67
	.dc.l	fe_ftan		;$FE68
	.dc.l	fe_fatan	;$FE69
	.dc.l	fe_flog		;$FE6A
	.dc.l	fe_fexp		;$FE6B
	.dc.l	fe_fsqr		;$FE6C
	.dc.l	fe_fpi		;$FE6D
	.dc.l	fe_fnpi		;$FE6E
	.dc.l	fe_fpower	;$FE6F
	.dc.l	fe_frnd		;$FE70
	.dc.l	fe_fsinh	;$FE71
	.dc.l	fe_fcosh	;$FE72
	.dc.l	fe_ftanh	;$FE73
	.dc.l	fe_fatanh	;$FE74
	.dc.l	fe_fasin	;$FE75
	.dc.l	fe_facos	;$FE76
	.dc.l	fe_flog10	;$FE77
	.dc.l	fe_flog2	;$FE78
	.dc.l	fe_ffrexp	;$FE79
	.dc.l	fe_fldexp	;$FE7A
	.dc.l	fe_faddone	;$FE7B
	.dc.l	fe_fsubone	;$FE7C
	.dc.l	fe_fdivtwo	;$FE7D
	.dc.l	fe_fieecnv	;$FE7E
	.dc.l	fe_ieefcnv	;$FE7F
	.dcb.l	96,fe_undefined
	.dc.l	fe_clmul	;$FEE0
	.dc.l	fe_cldiv	;$FEE1
	.dc.l	fe_clmod	;$FEE2
	.dc.l	fe_cumul	;$FEE3
	.dc.l	fe_cudiv	;$FEE4
	.dc.l	fe_cumod	;$FEE5
	.dc.l	fe_cltod	;$FEE6
	.dc.l	fe_cdtol	;$FEE7
	.dc.l	fe_cltof	;$FEE8
	.dc.l	fe_cftol	;$FEE9
	.dc.l	fe_cftod	;$FEEA
	.dc.l	fe_cdtof	;$FEEB
	.dc.l	fe_cdcmp	;$FEEC
	.dc.l	fe_cdadd	;$FEED
	.dc.l	fe_cdsub	;$FEEE
	.dc.l	fe_cdmul	;$FEEF
	.dc.l	fe_cddiv	;$FEF0
	.dc.l	fe_cdmod	;$FEF1
	.dc.l	fe_cfcmp	;$FEF2
	.dc.l	fe_cfadd	;$FEF3
	.dc.l	fe_cfsub	;$FEF4
	.dc.l	fe_cfmul	;$FEF5
	.dc.l	fe_cfdiv	;$FEF6
	.dc.l	fe_cfmod	;$FEF7
	.dc.l	fe_cdtst	;$FEF8
	.dc.l	fe_cftst	;$FEF9
	.dc.l	fe_cdinc	;$FEFA
	.dc.l	fe_cfinc	;$FEFB
	.dc.l	fe_cddec	;$FEFC
	.dc.l	fe_cfdec	;$FEFD
	.dc.l	fe_fevarg	;$FEFE
	.dc.l	fe_fevecs	;$FEFF

;----------------------------------------------------------------
;未定義のFEファンクションコール
fe_undefined::
	exit

;----------------------------------------------------------------
;$FE00	__LMUL
;	4バイト符号つき整数どうしの乗算をします。
;<d0.l:被乗数
;<d1.l:乗数
;>d0.l:演算結果
;>c-flag:cs=エラー(オーバーフロー)
fe_lmul::
	muls.l	d1,d0
	svs.b	d7
	neg.b	d7
	exit	D7

;----------------------------------------------------------------
;$FE01	__LDIV
;	4バイト符号つき整数どうしの除算をします。
;<d0.l:被除数
;<d1.l:除数
;>d0.l:演算結果
;>c-flag:cs=エラー(除数が0)
fe_ldiv::
	tst.l	d1
	beq	@f
	divs.l	d1,d0
	exit	_

@@:	exit	C

;----------------------------------------------------------------
;$FE02	__LMOD
;	4バイト符号つき整数どうしの除算の剰余を計算します。
;<d0.l:被除数
;<d1.l:除数
;>d0.l:演算結果
;>c-flag:cs=エラー(除数が0)
fe_lmod::
	tst.l	d1
	beq	@f
	move.l	d1,-(sp)
	exg.l	d0,d1
	divsl.l	d0,d0:d1
	exit	_,d1

@@:	exit	C

;----------------------------------------------------------------
;$FE04	__UMUL
;	4バイト符号なし整数どうしの乗算をします。
;<d0.l:被乗数
;<d1.l:乗数
;>d0.l:演算結果
;>c-flag:cs=エラー(オーバーフロー)
fe_umul::
	mulu.l	d1,d0
	svs.b	d7
	neg.b	d7
	exit	D7

;----------------------------------------------------------------
;$FE05	__UDIV
;	4バイト符号なし整数どうしの除算をします。
;<d0.l:被除数
;<d1.l:除数
;>d0.l:演算結果
;>c-flag:cs=エラー(除数が0)
fe_udiv::
	tst.l	d1
	beq	@f
	divu.l	d1,d0
	exit	_

@@:	exit	C

;----------------------------------------------------------------
;$FE06	__UMOD
;	4バイト符号なし整数どうしの除算の剰余を計算します。
;<d0.l:被除数
;<d1.l:除数
;>d0.l:演算結果
;>c-flag:cs=エラー(除数が0)
fe_umod::
	tst.l	d1
	beq	@f
	move.l	d1,-(sp)
	exg.l	d0,d1
	divsl.l	d0,d0:d1
	exit	_,d1

@@:	exit	C

;----------------------------------------------------------------
;$FE08	__IMUL
;	4バイト符号なし整数どうしの乗算をします。
;<d0.l:被乗数
;<d1.l:乗数
;>d0.l:演算結果の上位4バイト
;>d1.l:演算結果の下位4バイト
fe_imul::
	move.l	d1,d7
	mulu.l	d0,d1
	bvs	@f
	moveq.l	#0,d0
	exit

@@:	move.l	d3,-(sp)
		move.l	d2,-(sp)
	move.l	d7,d1
	move.l	d0,d3
	swap.w	d3
	swap.w	d7
	move.w	d3,d2
	mulu.w	d1,d2
	mulu.w	d0,d1
	mulu.w	d7,d0
	mulu.w	d3,d7
	add.l	d2,d0
		clr.w	d3
	addx.w	d3,d3
	swap.w	d1
	add.w	d0,d1
	swap.w	d1
	move.w	d3,d0
	swap.w	d0
	addx.l	d7,d0
	exit	d2,d3

;----------------------------------------------------------------
;$FE09	__IDIV
;	4バイト符号なし整数どうしの除算をします。
;<d0.l:被除数
;<d1.l:除数
;>d0.l:演算結果(商)
;>d1.l:演算結果(剰余)
;>c-flag:cs=エラー(除数が0)
fe_idiv::
	tst.l	d1
	beq	@f
	divul.l	d1,d1:d0
	exit	_

@@:	exit	C

;----------------------------------------------------------------
;$FE0C	__RANDOMIZE
;	-32768から32767までの範囲で乱数のもとをセットします。
;<d0.l:4バイト符号つき整数
;	引数の値が正しくない場合、乱数は初期化されません。
fe_randomize::
	bsr	randomize
	moveq.l	#0,d0
	exit

;?d0/d7/a6
randomize::
	lea.l	(rnd_table,pc),a6
	moveq.l	#54,d7
@@:	mulu.w	#15625,d0
	addq.w	#1,d0
	move.w	d0,(a6)+
	move.w	d0,(a6)+
	dbra	d7,@b
	move.w	#54,rnd_count
	bsr	rnd_shuffle
	bsr	rnd_shuffle
;;;	bsr	rnd_shuffle
;?d0/d7/a6
rnd_shuffle::
	lea.l	(rnd_table,pc),a6
	moveq.l	#24-1,d7
@@:	move.l	(4*31,a6),d0
	sub.l	d0,(a6)+
	dbra	d7,@b
	moveq.l	#31-1,d7
@@:	move.l	(-4*24,a6),d0
	sub.l	d0,(a6)+
	dbra	d7,@b
	rts

rnd_count::
	.dc.w	-1
rnd_table::
	.dcb.l	55,0

;----------------------------------------------------------------
;$FE0D	__SRAND
;	0から65535までの範囲で乱数のもとをセットします。
;<d0.l:4バイト符号つき整数
;	引数の値が正しくない場合、乱数は初期化されません。
fe_srand::
	bsr	srand
	moveq.l	#0,d0
	exit

;?d0/d7/a6
srand::
	lea.l	(rand_table,pc),a6
	moveq.l	#54,d7
@@:	mulu.w	#15625,d0
	addq.w	#1,d0
	move.w	d0,(a6)+
	dbra	d7,@b
	move.w	#54,rand_count
;;;	bsr	rand_shuffle
;?d0/d7/a6
rand_shuffle::
	lea.l	(rand_table,pc),a6
	moveq.l	#24-1,d7
@@:	move.w	(2*31,a6),d0
	sub.w	d0,(a6)+
	dbra	d7,@b
	moveq.l	#31-1,d7
@@:	move.w	(-2*24,a6),d0
	sub.w	d0,(a6)+
	dbra	d7,@b
	rts

rand_count::
	.dc.w	-1
rand_table::
	.dcb.w	55,0

;----------------------------------------------------------------
;$FE0E	__RAND
;	4バイト符号つき整数の乱数を返します。
;>d0.l:4バイト符号つき整数(0以上32767以内)
1:	moveq.l	#51,d0
	bsr	srand
fe_rand::
	move.w	(rand_count,pc),d0
	bmi	1b
	cmp.w	#54,d0
	bne	2f
	bsr	rand_shuffle
	moveq.l	#-1,d0
2:	addq.w	#1,d0
	move.w	d0,rand_count
	move.w	(rand_table,pc,d0.w*2),d0
	and.l	#$00007FFF,d0
	exit

;----------------------------------------------------------------
;$FE10	__STOL
;	文字列を4バイト符号つき整数に変換します。
;<a0.l:文字列を指すポインタ
;>d0.l:変換された4バイト符号つき整数
;>c-flag:cs=エラー
;>n-flag:(cs)mi=数値の記述法がおかしい
;>v-flag:(cs)vs=オーバーフロー
fe_stol::
	moveq.l	#' ',d7
		moveq.l	#0,d0
1:	move.b	(a0)+,d0
		cmp.b	d7,d0
	beq	1b
	cmp.b	#9,d0
	beq	1b
	cmp.b	#'+',d0
	beq	2f
	cmp.b	#'-',d0
	bne	3f
	moveq.l	#0,d7
2:	move.b	(a0)+,d0
3:	sub.b	#'0',d0
	bcs	6f
	cmp.b	#10,d0
	bcc	6f
	movea.w	d7,a6			;0=負,その他=正
		move.b	(a0)+,d7
	sub.b	#'0',d7
	bcs	5f
	cmp.b	#10,d7
	bcc	5f
4:	mulu.l	#10,d0
	bvs	8f
	add.l	d7,d0
	bcs	8f
	move.b	(a0)+,d7
		sub.b	#'0',d7
	bcs	5f
	cmp.b	#10,d7
	bcs	4b
5:	subq.w	#1,a0
		move.w	a6,d7
	beq	7f
;正
	tst.l	d0
	bmi	9f
	exit	_

;数値の記述法がおかしい
6:	subq.w	#1,a0
	exit	C,N

;負
7:	neg.l	d0
		tst.l	d0
	bgt	9f
	exit	_

;オーバーフロー
8:	subq.w	#1,a0
9:	exit	C,V

;----------------------------------------------------------------
;$FE11	__LTOS
;	4バイト符号つき整数を文字列に変換します。
;<d0.l:4バイト符号つき整数
;<a0.l:変換された文字列の格納用バッファを指すポインタ
;>(a0):変換された文字列
fe_ltos::
	tst.l	d0
	beq	8f
	movem.l	d0-d1,-(sp)		;フラグ保存
	bpl	1f
	move.b	#'-',(a0)+
		neg.l	d0
1:	lea.l	9f(pc),a6
2:	cmp.l	(a6)+,d0
	bcs	2b
	move.l	-4(a6),d1
3:	moveq.l	#'0'-1,d7
4:	addq.b	#1,d7
		sub.l	d1,d0
	bcc	4b
	move.b	d7,(a0)+
		add.l	d1,d0
	move.l	(a6)+,d1
	bne	3b
	clr.b	(a0)
	exit	d0,d1

8:	move.b	#'0',(a0)+
		clr.b	(a0)
	exit

9:	.dc.l	1000000000
	.dc.l	100000000
	.dc.l	10000000
	.dc.l	1000000
	.dc.l	100000
	.dc.l	10000
	.dc.l	1000
	.dc.l	100
	.dc.l	10
	.dc.l	1
	.dc.l	0

;----------------------------------------------------------------
;$FE12	__STOH
;	16進数を表す文字列を4バイト符号なし整数に変換します。
;<a0.l:文字列を指すポインタ
;>d0.l:変換された4バイト符号なし整数
;>c-flag:cs=エラー
;>n-flag:(cs)mi=数値の記述法がおかしい
;>v-flag:(cs)vs=オーバーフロー
fe_stoh::
	bsr	stoh
	exit	D7

;16進数を表す文字列を4バイト符号なし整数に変換します。
;<a0.l:文字列を指すポインタ
;>d0.l:変換された4バイト符号なし整数
;>d7.b:CCR
;>z-flag:ne=エラー
stoh:
	moveq.l	#-'0',d7
		add.b	(a0)+,d7
	bmi	3f
	moveq.l	#0,d0
	cmp.b	#10,d7
	bcs	1f
	and.b	#$DF,d7
		subq.b	#'A'-('9'+1),d7
	cmp.b	#10,d7
	bcs	3f
	cmp.b	#16,d7
	bcc	3f
1:	or.b	d7,d0
		moveq.l	#-'0',d7
	add.b	(a0)+,d7
	bmi	4f
	cmp.b	#10,d7
	bcs	2f
	and.b	#$DF,d7
		subq.b	#'A'-('9'+1),d7
	cmp.b	#10,d7
	bcs	4f
	cmp.b	#16,d7
	bcc	4f
2:	mulu.l	#16,d0
	bvc	1b
	subq.w	#1,a0
	moveq.l	#0|0|0|V|C,d7
	rts

3:	subq.w	#1,a0
	moveq.l	#0|N|0|0|C,d7
	rts

4:	subq.w	#1,a0
	moveq.l	#0,d7
	rts

;----------------------------------------------------------------
;$FE13	__HTOS
;	4バイト符号なし整数を16進数表現の文字列に変換します。
;<d0.l:4バイト符号なし整数
;<a0.l:変換された文字列の格納用バッファを指すポインタ
;>(a0):変換された文字列
fe_htos::
	tst.l	d0
	beq	8f
	move.l	d1,-(sp)		;d0は元に戻るので保護する必要がない
		moveq.l	#8-1,d1
1:	rol.l	#4,d0
		moveq.l	#$0F,d7
	and.b	d0,d7
	dbne	d1,1b
	bra	3f

2:	rol.l	#4,d0
		moveq.l	#$0F,d7
	and.b	d0,d7
3:	move.b	9f(pc,d7.w),(a0)+
	dbra	d1,2b
	clr.b	(a0)
	exit	d1

8:	move.b	#'0',(a0)+
		clr.b	(a0)
	exit

9:	.dc.b	'0123456789ABCDEF'

;----------------------------------------------------------------
;$FE14	__STOO
;	8進数を表す文字列を4バイト符号なし整数に変換します。
;<a0.l:文字列を指すポインタ
;>d0.l:変換された4バイト符号なし整数
;>c-flag:cs=エラー
;>n-flag:(cs)mi=数値の記述法がおかしい
;>v-flag:(cs)vs=オーバーフロー
fe_stoo::
	bsr	stoo
	exit	D7

;8進数を表す文字列を4バイト符号なし整数に変換します。
;<a0.l:文字列を指すポインタ
;>d0.l:変換された4バイト符号なし整数
;>d7.b:CCR
;>z-flag:ne=エラー
stoo:
	moveq.l	#-('7'+1),d7
		add.b	(a0)+,d7
	bpl	2f
	addq.b	#8,d7
	bmi	2f
	moveq.l	#0,d0
1:	or.b	d7,d0
		moveq.l	#-('7'+1),d7
	add.b	(a0)+,d7
	bpl	3f
	addq.b	#8,d7
	bmi	3f
	mulu.l	#8,d0
	bvc	1b
	subq.w	#1,a0
	moveq.l	#0|0|0|V|C,d7
	rts

2:	subq.w	#1,a0
	moveq.l	#0|N|0|0|C,d7
	rts

3:	subq.w	#1,a0
	moveq.l	#0,d7
	rts

;----------------------------------------------------------------
;$FE15	__OTOS
;	4バイト符号なし整数を8進数表現の文字列に変換します。
;<d0.l:4バイト符号なし整数
;<a0.l:変換された文字列の格納用バッファを指すポインタ
;>(a0):変換された文字列
fe_otos::
	tst.l	d0
	beq	8f
	move.l	d1,-(sp)		;d0は元に戻るので保護する必要がない
	moveq.l	#11-1,d1
		rol.l	#2,d0
	moveq.l	#$03,d7
		and.b	d0,d7
	bne	3f
	moveq.l	#10-1,d1
1:	rol.l	#3,d0
		moveq.l	#$07,d7
	and.b	d0,d7
	dbne	d1,1b
	bra	3f

2:	rol.l	#3,d0
		moveq.l	#$07,d7
	and.b	d0,d7
3:	add.b	#'0',d7
		move.b	d7,(a0)+
	dbra	d1,2b
	clr.b	(a0)
	exit	d1

8:	move.b	#'0',(a0)+
		clr.b	(a0)
	exit

;----------------------------------------------------------------
;$FE16	__STOB
;	2進数を表す文字列を4バイト符号なし整数に変換します。
;<a0.l:文字列を指すポインタ
;>d0.l:変換された4バイト符号なし整数
;>c-flag:cs=エラー
;>n-flag:(cs)mi=数値の記述法がおかしい
;>v-flag:(cs)vs=オーバーフロー
fe_stob::
	bsr	stob
	exit	D7

;2進数を表す文字列を4バイト符号なし整数に変換します。
;<a0.l:文字列を指すポインタ
;>d0.l:変換された4バイト符号なし整数
;>d7.b:CCR
;>z-flag:ne=エラー
stob:
	moveq.l	#-('1'+1),d7
		add.b	(a0)+,d7
	bpl	2f
	addq.b	#2,d7
	bmi	2f
	moveq.l	#0,d0
1:	or.b	d7,d0
		moveq.l	#-('1'+1),d7
	add.b	(a0)+,d7
	bpl	3f
	addq.b	#2,d7
	bmi	3f
	add.l	d0,d0
	bcc	1b
	subq.w	#1,a0
	moveq.l	#0|0|0|V|C,d7
	rts

2:	subq.w	#1,a0
	moveq.l	#0|N|0|0|C,d7
	rts

3:	subq.w	#1,a0
	moveq.l	#0,d7
	rts

;----------------------------------------------------------------
;$FE17	__BTOS
;	4バイト符号なし整数を2進数表現の文字列に変換します。
;<d0.l:4バイト符号なし整数
;<a0.l:変換された文字列の格納用バッファを指すポインタ
;>(a0):変換された文字列
fe_btos::
	tst.l	d0
	beq	8f
	move.l	d1,-(sp)		;d0は元に戻るので保護する必要がない
	moveq.l	#32-1,d1
1:	rol.l	#1,d0
		moveq.l	#$01,d7
	and.b	d0,d7
	dbne	d1,1b
	bra	3f

2:	rol.l	#1,d0
		moveq.l	#$01,d7
	and.b	d0,d7
3:	add.b	#'0',d7
		move.b	d7,(a0)+
	dbra	d1,2b
	clr.b	(a0)
	exit	d1

8:	move.b	#'0',(a0)+
		clr.b	(a0)
	exit

;----------------------------------------------------------------
;$FE18	__IUSING
;	4バイト符号つき整数を文字列に変換します。
;<d0.l:4バイト符号つき整数
;<d1.l:桁数
;<a0.l:変換された文字列の格納用バッファを指すポインタ
;<(a0):変換された文字列
fe_iusing::
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	tst.l	d0
	beq	6f
	lea.l	9f(pc),a6
	bmi	7f
;正
1:	addq.w	#1,d1
	cmp.l	(a6)+,d0
	bcs	1b
	sub.w	#12,d1
	bmi	3f
	moveq.l	#' ',d7
2:	move.b	d7,(a0)+
	dbra	d1,2b
3:	move.l	-4(a6),d1
4:	moveq.l	#'0'-1,d7
5:	addq.b	#1,d7
	sub.l	d1,d0
	bcc	5b
	add.l	d1,d0
	move.b	d7,(a0)+
	move.l	(a6)+,d1
	bne	4b
	clr.b	(a0)
	exit	d0,d1

;0
6:	subq.w	#2,d1
	bmi	3f
	moveq.l	#' ',d7
2:	move.b	d7,(a0)+
	dbra	d1,2b
3:	move.b	#'0',(a0)+
	clr.b	(a0)
	exit	d0,d1

;負
7:	neg.l	d0
1:	addq.w	#1,d1
	cmp.l	(a6)+,d0
	bcs	1b
	sub.w	#13,d1
	bmi	3f
	moveq.l	#' ',d7
2:	move.b	d7,(a0)+
	dbra	d1,2b
3:	move.b	#'-',(a0)+
	move.l	-4(a6),d1
4:	moveq.l	#'0'-1,d7
5:	addq.b	#1,d7
	sub.l	d1,d0
	bcc	5b
	add.l	d1,d0
	move.b	d7,(a0)+
	move.l	(a6)+,d1
	bne	4b
	clr.b	(a0)
	exit	d0,d1

9:	.dc.l	1000000000
	.dc.l	100000000
	.dc.l	10000000
	.dc.l	1000000
	.dc.l	100000
	.dc.l	10000
	.dc.l	1000
	.dc.l	100
	.dc.l	10
	.dc.l	1
	.dc.l	0

;----------------------------------------------------------------
;$FE1A	__LTOD
;	4バイト符号つき整数を8バイト浮動小数点数に変換します。
;<d0.l:4バイト符号つき整数
;>d0-d1:変換された8バイト浮動小数点数
fe_ltod::
	fmove.l	d0,fp0
	fmove.d	fp0,-(sp)
	exit	d0,d1

;----------------------------------------------------------------
;$FE1B	__DTOL
;	8バイト浮動小数点数を4バイト符号つき整数に変換します。
;<d0-d1:8バイト浮動小数点数
;>d0.l:変換された4バイト符号つき整数
;>c-flag:cs=エラー(変換結果が4バイト符号つき整数の値の範囲を超えた)
;	小数部分は切り捨てられます。
;	4バイト符号つき整数の値は次の範囲です。
;		-2147483648~+2147483647
fe_dtol::
	fmove.l	#$00000000,fpsr
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fintrz.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fmove.l	fp0,d0
	fmove.l	fpsr,d7
	and.b	#i|v|0|0|0|0|0|0,d7	;iv000000
	bne	@f
	exit

@@:	add.b	d7,d7			;v0000000
	rol.b	#2,d7			;000000v0
	addq.b	#0|0|0|0|C,d7		;000000vc
	exit	D7

;----------------------------------------------------------------
;$FE1C	__LTOF
;	4バイト符号つき整数を4バイト浮動小数点数に変換します。
;<d0.l:4バイト符号つき整数
;<d0.l:変換された4バイト浮動小数点数
fe_ltof::
	fmove.l	d0,fp0
	fmove.s	fp0,d0
	exit

;----------------------------------------------------------------
;$FE1D	__FTOL
;	4バイト浮動小数点数を4バイト符号つき整数に変換します。
;<d0.l:4バイト浮動小数点数
;>d0.l:変換された4バイト符号つき整数
;>c-flag:cs=エラー(変換結果が4バイト符号つき整数の値の範囲を超えた)
;	小数部分は切り捨てられます。
;	4バイト符号つき整数の値は次の範囲です。
;		-2147483648~+2147483647
fe_ftol::
	fmove.l	#$00000000,fpsr
	fintrz.s	d0,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fmove.l	fp0,d0
	fmove.l	fpsr,d7
	and.b	#i|v|0|0|0|0|0|0,d7	;iv000000
	bne	@f
	exit

@@:	add.b	d7,d7			;v0000000
	rol.b	#2,d7			;000000v0
	addq.b	#0|0|0|0|C,d7		;000000vc
	exit	D7

;----------------------------------------------------------------
;$FE1E	__FTOD
;	4バイト浮動小数点数を8バイト浮動小数点数に変換します。
;<d0.l:4バイト浮動小数点数
;>d0-d1:変換された8バイト浮動小数点数
fe_ftod::
	fmove.s	d0,fp0
	fmove.d	fp0,-(sp)
	exit	d0,d1

;----------------------------------------------------------------
;$FE1F	__DTOF
;	8バイト浮動小数点数を4バイト浮動小数点数に変換します。
;<d0-d1:8バイト浮動小数点数
;>d0.l:変換された4バイト浮動小数点数
;>c-flag:cs=エラー(引数が4バイト浮動小数点数で表現できない)
fe_dtof::
	fmove.l	#$00000000,fpsr
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fmove.s	fp0,d0
	fmove.l	fpsr,d7
	and.b	#i|v|0|0|0|0|0|0,d7	;iv000000
	bne	@f
	exit

@@:	add.b	d7,d7			;v0000000
	rol.b	#2,d7			;000000v0
	addq.b	#0|0|0|0|C,d7		;000000vc
	exit	D7

;----------------------------------------------------------------
;$FE20	__VAL
;	文字列を8バイト浮動小数点数に変換します。
;<a0.l:文字列を指すポインタ
;>d0-d1:変換された8バイト浮動小数点数
;>c-flag:cs=エラー
;>n-flag:(cs)mi=数値の記述法がおかしい
;>v-flag:(cs)vs=オーバーフロー
;	文字列が10進数以外の場合、その先頭には、2進数では'&B'、8進数では'&O'、
;	16進数では'&H'が必要です。
;	10進数の場合、返り値として次のものが追加されます。
;		d2.w	整数フラグ
;		d3.l	整数値
;	文字列が整数(小数部及び指数部がない)で、かつ4バイト符号つき整数で表現可能な場合、
;	整数フラグは$FFFFで、整数値にその値がはいります。
;	それ以外の場合は整数フラグは0となります。
fe_val::
1:	move.b	(a0)+,d0
	cmp.b	#' ',d0
	beq	1b
	cmp.b	#9,d0
	beq	1b
	cmp.b	#'&',d0
	beq	2f
	subq.w	#1,a0
	bra	fe_stod

2:	moveq.l	#0,d2			;整数フラグ
	moveq.l	#0,d3
	move.b	(a0)+,d0
	cmp.b	#'H',d0
	beq	3f
	cmp.b	#'B',d0
	beq	4f
	cmp.b	#'O',d0
	beq	5f
	subq.w	#1,a0			;純正品は戻していない
	exit	C,N

3:	bsr	stoh
	bne	6f
	bra	fe_ltod

4:	bsr	stob
	bne	6f
	bra	fe_ltod

5:	bsr	stoo
	bne	6f
	bra	fe_ltod

6:	exit	D7

;----------------------------------------------------------------
;$FE21	__USING
;	8バイト浮動小数点数を文字列に変換します。
;<d0-d1:8バイト浮動小数点数
;<d2.l:整数部分の桁数
;<d3.l:小数部分の桁数
;<d4.l:アトリビュート
;<a0.l:変換された文字列の格納用バッファを指すポインタ
;>(a0):変換された文字列
;	アトリビュートはビット0~6をセットすることにより以下のような数値表現ができます。
;	ビット0:左側を'*'でパッティングします。
;	ビット1:'\'を先頭に付加します。
;	ビット2:整数部分を3桁ごとに','で区切ります。
;	ビット3:指数形式で表現します。
;	ビット4:正数の場合'+'を先頭に付加します。
;	ビット5:正数の場合'+'を、負数の場合'-'を最後尾に付加します。
;	ビット6:正数の場合' 'を、負数の場合'-'を最後尾に付加します。
fe_using::
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
	bsr	using
	exit

;----------------------------------------------------------------
;using
;浮動小数点数を文字列に変換する
;<fp0:浮動小数点数(#INFや#NANは不可)
;<d2.l:整数部の桁数(負数は不可,アトリビュートで指定しない限り負符号を含む桁数,
;	指数形式を指定しない限り入り切らなければ何桁でもはみ出す)
;<d3.l:小数部の桁数(負数は不可,0でも小数点を書く,-1のとき小数点を書かない)
;<d4.l:アトリビュート
;	bit0	左側が余っていたら'*'で埋める(整数部の桁数に含まれる,指数形式では無効)
;	bit1	先頭に'\'を付ける(整数部の桁数に含まれる,指数形式では無効,符号と数字の間に入る)
;	bit2	整数部を3桁毎に','で区切る(整数部の桁数に含まれる,指数形式では無効)
;	bit3	指数形式(整数部の桁数から符号' 'or'-'を除いた桁数の位置に小数点を置く)
;	bit4	先頭に正のとき'+',負のとき'-'を付ける(整数部の桁数に含まれない)
;	bit5	末尾に正のとき'+',負のとき'-'を付ける(小数部の桁数に含まれない)
;	bit6	末尾に正のとき' ',負のとき'-'を付ける(小数部の桁数に含まれない)
;<a0.l:バッファの先頭
;>(a0):文字列
;>a0.l:文字列の末尾の0の位置
;*a0,?d0-d4/d7/fp0
using:
	movem.l	d5-d6,-(sp)
;整数部の桁数の調整
	tst.l	d2
	bgt	@f
	moveq.l	#1,d2			;整数部は少なくとも1桁必要
@@:
;指数形式かどうかで分岐
	btst.l	#3,d4
	bne	usingExp		;指数形式
;指数形式ではないとき
usingNotExp:
;小数部の桁数の調整
	cmp.l	#-1,d3
	bge	@f
	moveq.l	#-1,d3			;指数形式でないとき小数部の桁数は-1以上
@@:
;10進正規化
	bsr	dexp
;整数部が入り切るように桁数を調整する
	cmp.l	d2,d0
	blt	@f
	move.l	d0,d2
@@:
;左側のスペースを書き込む
	movea.l	a0,a6			;バッファの先頭
;<a6.l:バッファの先頭
	move.l	d2,d5			;整数部の桁数(1以上)
	move.l	d0,d2
	sub.l	d0,d5			;スペースの桁数
	beq	2f
	move.l	d5,d0			;スペースの桁数
1:	move.b	#' ',(a0)+
	subq.l	#1,d0
	bne	1b
2:
;<d5.l:スペースの桁数
;文字列に変換する
	move.l	d2,d6			;整数部の桁数(1以上)
	add.l	d3,d6			;スペースを除く桁数(1以上)
	tst.l	d3
	bpl	@f
	addq.l	#1,d6			;小数点以下の桁数が-1だったときは0とみなす
@@:
;<d6.l:スペースを除く桁数
	move.l	d6,d0			;スペースを除く桁数(1以上)
1:	fmul.s	#0f10,fp0
	fintrz.x	fp0,fp1
	fmove.l	fp1,d7
	add.b	#'0',d7			;'0'~'9'にする
	fsub.x	fp1,fp0
	move.b	d7,(a0)+
	subq.l	#1,d0
	bne	1b
2:
;四捨五入
	fcmp.s	#0f0.5,fp0
	fblt	3f			;次の桁が5未満なので切り捨てる
;繰り上げる
	move.l	d6,d0			;スペースを除く桁数(1以上)
1:	addq.b	#1,-(a0)		;繰り上がり
	cmpi.b	#'9',(a0)
	bls	3f			;上の位に納まったので終わり
	move.b	#'0',(a0)		;上の位も溢れた
	subq.l	#1,d0
	bne	1b
2:
;最上位から繰り上がった
	addq.l	#1,d2			;整数部の桁数が1増える
	subq.l	#1,d5			;スペースの桁数を減らす
	bcc	@f			;スペースがあった
	move.b	#'0',(a6,d6.l)		;スペースがなかったので右にずらす
	lea.l	(1,a6),a0
	moveq.l	#0,d5
@@:	move.b	#'1',-(a0)		;先頭の1を書く
	addq.l	#1,d6			;スペースを除く桁数が1増えた
3:
;文字列の末尾の0(番兵)を置く
	lea.l	(a6,d5.l),a0		;数字の先頭
	clr.b	(a0,d6.l)		;末尾の0を書き込む(文字列シフトのときの番兵に必要)
;小数点を入れる(小数点以下の桁数が0でも入れる,-1のときは入れない)
	tst.l	d3			;小数点以下の桁数
	bmi	@f			;-1のときは小数点を入れない
	adda.l	d2,a0			;小数点の位置
	bsr	usingShiftRight		;右にずらす
	move.b	#'.',(a0)		;小数点を書く
	addq.l	#1,d6			;スペースを除く桁数が1増えた
@@:
;整数部を3桁毎に','で区切る
	btst.l	#2,d4
	beq	3f
	move.l	d2,d0			;整数部の桁数
;以降ではd2は不要
	bra	2f

1:	lea.l	(a6,d5.l),a0		;数字の先頭
	subq.l	#1,d5			;スペースの桁数を1減らす
	bcc	4f
;スペースがないので右にずらす
	moveq.l	#0,d5
	adda.l	d0,a0			;','を入れる位置
	bsr	usingShiftRight		;右にずらす
	bra	5f

;スペースがあるので左にずらす
;<d0.l:','の左側の数字の桁数=ずらす範囲の桁数
;<a0.l:数字の先頭=ずらす範囲の先頭
4:	bsr	usingShiftLeft		;左にずらす
;<a0.l:ずらしてできた隙間の位置
5:	move.b	#',',(a0)
;;;	addq.l	#1,d2			;整数部の桁数が1増えた
	addq.l	#1,d6			;スペースを除く桁数が1増えた
2:	subq.l	#3,d0
	bgt	1b
3:
;先頭に'\'を付ける
	btst.l	#1,d4
	beq	2f
	subq.l	#1,d5
	bcc	1f
	moveq.l	#0,d5
	movea.l	a6,a0
	bsr	usingShiftRight
1:	move.b	#'\',(a6,d5.l)
;;;	addq.l	#1,d2			;整数部の桁数が1増えた
	addq.l	#1,d6			;スペースを除く桁数が1増えた
2:
;先頭に正のとき'+',負のとき'-'を付ける
	btst.l	#4,d4
	beq	2f
	lea.l	(a6,d5.l),a0		;スペースの直後
	bsr	usingShiftRight		;無条件に隙間を空ける
	addq.l	#1,d6			;スペースを除く桁数が1増えた
	moveq.l	#'+',d0			;正のとき'+'
	add.l	d1,d0
	add.l	d1,d0			;負のとき'-'
	move.b	d0,(a0)
	bra	3f
2:
;末尾に正のとき'+',負のとき'-'を付ける
	btst.l	#5,d4
	beq	2f
	lea.l	(a6,d5.l),a0		;スペースの直後
	adda.l	d6,a0			;末尾の0の位置
	moveq.l	#'+',d0			;正のとき'+'
	add.l	d1,d0
	add.l	d1,d0			;負のとき'-'
	move.b	d0,(a0)+
	clr.b	(a0)
	addq.l	#1,d6			;スペースを除く桁数が1増えた
	bra	3f
2:
;末尾に正のとき' ',負のとき'-'を付ける
	btst.l	#6,d4
	beq	2f
	lea.l	(a6,d5.l),a0		;スペースの直後
	adda.l	d6,a0			;末尾の0の位置
	tst.l	d1
	sne.b	d0
	and.b	#'-'-' ',d0
	add.b	#' ',d0
	move.b	d0,(a0)+
	clr.b	(a0)
	addq.l	#1,d6			;スペースを除く桁数が1増えた
	bra	3f
2:
;負符号を付ける
	tst.l	d1
	beq	2f			;正数
	subq.l	#1,d5
	bcc	1f
	moveq.l	#0,d5
	movea.l	a6,a0
	bsr	usingShiftRight
1:	move.b	#'-',(a6,d5.l)
;;;	addq.l	#1,d2			;整数部の桁数が1増えた
	addq.l	#1,d6			;スペースを除く桁数が1増えた
2:
;符号終わり
3:
;左側が余っていたら'*'で埋める
	btst.l	#0,d4
	beq	2f
	tst.l	d5
	beq	2f			;スペースがない
	movea.l	a6,a0			;バッファの先頭
;;;	add.l	d5,d2			;小数点の左側の桁数
	add.l	d5,d6			;スペースを除く桁数
1:	move.b	#'*',(a0)+
	subq.l	#1,d5
	bne	1b
2:	lea.l	(a6,d5.l),a0		;'*'で埋めなかったとき必要
	adda.l	d6,a0
	clr.b	(a0)			;文字列の末尾
	movem.l	(sp)+,d5-d6
	rts


;指数形式のとき
usingExp:
;小数部の桁数の調整
	tst.l	d3
	bge	@f
	moveq.l	#0,d3			;指数形式のとき小数部の桁数は0以上
@@:
;符号の確認
;>d5.l:
;	bit0~7		先頭に正のとき付ける文字
;	bit8~15	末尾に正のとき付ける文字
;	bit16~23	先頭に負のとき付ける文字
;	bit24~31	末尾に負のとき付ける文字
	move.l	#('-'<<16)+('+'<<0),d5	;先頭に正のとき'+',負のとき'-'を付ける
;0,'-',0,'+'
	btst.l	#4,d4			;bit4をテスト
	bne	@f
	lsl.l	#8,d5			;末尾に正のとき'+',負のとき'-'を付ける
;'-',0,'+',0
	btst.l	#5,d4			;bit5をテスト
	bne	@f
	move.w	#' '<<8,d5		;末尾に正のとき' ',負のとき'-'を付ける
;'-',0,' ',0
	btst.l	#6,d4			;bit6をテスト
	bne	@f
	lsr.l	#8,d5			;先頭に正のとき' ',負のとき'-'を付ける
;0,'-',0,' '
@@:
;>d5.w:
;	bit0~7		先頭に付ける文字
;	bit8~15	末尾に付ける文字
;桁数の調整
	and.b	#%01110000,d4
	bne	@f			;符号の指定があるときは符号の桁数は含まれていない
	subq.l	#1,d2			;符号の桁数を引く
	bgt	@f
	moveq.l	#1,d2			;整数部は最低1桁必要
@@:
	move.l	d2,d6			;整数部の桁数
;符号の確認
	ftst.x	fp0
	fbge	@f
	fneg.x	fp0,fp0
	swap.w	d5
@@:
;先頭の符号
	tst.b	d5
	beq	@f
	move.b	d5,(a0)+
@@:	lsr.w	#8,d5
;文字列に変換
	add.l	d3,d2			;全体の桁数
	bsr	ecvt			;d0-d2/d7/a6を破壊する,a0は末尾の0の位置
;<d0.l:10進指数部(浮動小数点数が0のときは1)
;<d1.l:ここでは常に0
;<d3.l:小数部の桁数
;<d5.b:末尾に付ける文字
;<d6.l:整数部の桁数
;<a0.l:末尾の0のアドレス
	suba.l	d3,a0			;小数点が入る位置
	movea.l	a0,a6
	suba.l	d6,a6			;数字の先頭
;<a6.l:数字の先頭
	bsr	usingShiftRight		;右にずらす
	move.b	#'.',(a0)+
	adda.l	d3,a0			;数字の末尾
;0サプレス(浮動小数点数が0のときだけ必要)
	cmpi.b	#'0',(a6)
	bne	2f
	move.l	d6,d1
	subq.l	#1,d1
1:	move.b	#' ',(a6)+
	subq.l	#1,d1
	bne	1b
2:
;指数部を書く
	move.b	#'E',(a0)+
	moveq.l	#'+',d1
	sub.l	d6,d0			;指数部
	bpl	@f
	moveq.l	#'-',d1
	neg.l	d0
@@:	move.b	d1,(a0)+
;<d0.l:指数(整数)
	cmp.l	#1000,d0
	blo	2f
	move.l	#1000,d1
	moveq.l	#'0'-1,d7
@@:	addq.b	#1,d7
	sub.l	d1,d0
	bcc	@b
	add.l	d1,d0
	move.b	d7,(a0)+
;指数を10進3桁で書く
;<d0.l:指数(整数)
2:	moveq.l	#100,d1
	moveq.l	#'0'-1,d7
@@:	addq.b	#1,d7
	sub.l	d1,d0
	bcc	@b
	add.l	d1,d0
	move.b	d7,(a0)+
	moveq.l	#10,d1
	moveq.l	#'0'-1,d7
@@:	addq.b	#1,d7
	sub.l	d1,d0
	bcc	@b
	add.l	d1,d0
	move.b	d7,(a0)+
	add.b	#'0',d0
	move.b	d0,(a0)+
;末尾の符号
	tst.b	d5
	beq	@f
	move.b	d5,(a0)+
@@:
	clr.b	(a0)			;文字列の末尾
	movem.l	(sp)+,d5-d6
	rts


;文字列を右に1桁ずらす
;<a0.l:ずらす範囲の先頭(末尾の0までずらす)
;>a0.l:変化しない
usingShiftRight:
	move.l	a0,-(sp)
@@:	tst.b	(a0)+
	bne	@b
@@:	move.b	-(a0),(1,a0)
	cmpa.l	(sp),a0
	bne	@b
	addq.l	#4,sp
	rts

;文字列を左に1桁ずらす
;<d0.l:ずらす範囲の桁数
;<a0.l:ずらす範囲の先頭(d0桁ずらす)
;>a0.l:ずらしてできた隙間の位置
usingShiftLeft:
	move.l	d0,-(sp)
	beq	2f
1:	move.b	(a0)+,(-2,a0)
	subq.l	#1,d0
	bne	1b
2:	subq.l	#1,a0
	move.l	(sp)+,d0
	rts

;----------------------------------------------------------------
;$FE22	__STOD
;	文字列を8バイト浮動小数点数に変換します。
;<a0.l:文字列を指すポインタ
;>d0-d1:変換された8バイト浮動小数点数
;>d2.w:整数フラグ
;>d3.l:整数値
;>c-flag:cs=エラー
;>n-flag:(cs)mi=数値の記述法がおかしい
;>v-flag:(cs)vs=オーバーフロー
;	文字列が整数(小数部及び指数部がない)で、かつ4バイト符号つき整数で表現可能な場合、
;	整数フラグは$FFFFで、整数値にその値がはいります。
;	それ以外の場合は整数フラグは0となります。

__	=	-128	;その他
BL	=	-6	;' '|$09
SH	=	-5	;'#'
DO	=	-4	;'.'
EX	=	-3	;'E'|'e'
PL	=	-2	;'+'
MI	=	-1	;'-'

;仮数部文字分類コードテーブル
table:
;		x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,xA,xB,xC,xD,xE,xF
	.dc.b	__,__,__,__,__,__,__,__,__,BL,__,__,__,__,__,__	;0x
	.dc.b	__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__	;1x
	.dc.b	BL,__,__,SH,__,__,__,__,__,__,__,PL,__,MI,DO,__	;2x
	.dc.b	+0,+1,+2,+3,+4,+5,+6,+7,+8,+9,__,__,__,__,__,__	;3x
	.dc.b	__,__,__,__,__,EX,__,__,__,__,__,__,__,__,__,__	;4x
	.dc.b	__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__	;5x
	.dc.b	__,__,__,__,__,EX,__,__,__,__,__,__,__,__,__,__	;6x
	.dc.b	__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__	;7x
	.dc.b	__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__	;8x
	.dc.b	__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__	;9x
	.dc.b	__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__	;Ax
	.dc.b	__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__	;Bx
	.dc.b	__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__	;Cx
	.dc.b	__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__	;Dx
	.dc.b	__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__	;Ex
	.dc.b	__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__	;Fx

err4:
	subq.w	#1,a0
err3:
	subq.w	#1,a0
err2:
	subq.w	#1,a0
;エラー
err:
	subq.w	#1,a0
	moveq.l	#0|N|0|0|C,d7
	rts

;'#I'
sharpI:
	cmp.b	#'N',(a0)+
	bne	err3
;'#IN'
	cmp.b	#'F',(a0)+
	bne	err4
;'#INF'
	or.l	#$7FF00000,d0		;符号はそのまま
	moveq.l	#$00000000,d1
	moveq.l	#0,d2
	moveq.l	#0,d3
	moveq.l	#0,d7
	rts

;'#'
sharp:
	moveq.l	#'I',d0
	sub.b	(a0)+,d0
	beq	sharpI			;'#I'
	addq.b	#'N'-'I',d0
	bne	err2
;'#N'
	cmp.b	#'A',(a0)+
	bne	err3
;'#NA'
	cmp.b	#'N',(a0)+
	bne	err4
;'#NAN'
	move.l	#$7FFFFFFF,d0		;符号は無視
	moveq.l	#$FFFFFFFF,d1
	moveq.l	#0,d2
	moveq.l	#0,d3
	moveq.l	#0,d7
	rts

@@:	exit	D7

;?d7/a6/fp0
fe_stod::
	pea.l	@b(pc)
stod:
	lea.l	table(pc),a6		;仮数部用文字コード分類テーブル
	moveq.l	#0,d0			;bit31:仮数部の符号(0=正,1=負)
					;bit15~0:小数点以下の桁数(ダウンカウント)
	moveq.l	#0,d1			;指数部
	moveq.l	#0,d7			;bit31:指数部の符号(0=正,1=負)
					;bit15~0:ワーク
	fmove.s	#0f0,fp0
blank:
	move.b	(a0)+,d7
	move.b	(a6,d7.w),d7
	bpl	int			;'0'~'9'
	addq.b	#-BL,d7
	beq	blank			;スペースまたはタブ
	subq.b	#-(BL-PL),d7
	bpl	sign			;符号
	addq.b	#PL-DO,d7
	beq	frac			;'.'
	addq.b	#DO-SH,d7
	beq	sharp			;'#'
	bra	err

;符号
sign:
	move.b	d7,d0			;0=正,1=負
	ror.l	#1,d0
;
	move.b	(a0)+,d7		;符号の直後の文字
	move.b	(a6,d7.w),d7
	bpl	int			;'0'~'9'
	addq.b	#-DO,d7
	beq	frac			;'.'
	addq.b	#DO-SH,d7
	beq	sharp			;'#'
	bra	err

;'0'~'9'(整数部)
1:	fmul.s	#0f10,fp0
;<d7.b:仮数部の1桁目の値
int:
	fadd.l	d7,fp0
	move.b	(a0)+,d7		;次の文字
	move.b	(a6,d7.w),d7
	bpl	1b			;'0'~'9'
	addq.b	#-EX,d7
	beq	exp0			;'E'または'e'
	addq.b	#EX-DO,d7
	bne	intChk0			;'0'~'9'|'E'|'e'|'.'以外
;'.'
	move.b	(a0)+,d7		;次の文字
	move.b	(a6,d7.w),d7
	bmi	2f
1:	subq.w	#1,d0			;小数点以下の桁数(ダウンカウント)
	fmul.s	#0f10,fp0
	fadd.l	d7,fp0
frac:
	move.b	(a0)+,d7		;次の文字
	move.b	(a6,d7.w),d7
	bpl	1b			;'0'~'9'
2:
;仮数部終わり
;符号を付ける
	tst.l	d0
	bpl	@f
	fneg.x	fp0,fp0
@@:
;<d7.b:仮数部の次の文字の分類コード
	addq.b	#-EX,d7
	bne	expChk			;小数点を動かして終わり
	bra	exp

exp0:
;符号を付ける
	tst.l	d0
	bpl	@f
	fneg.x	fp0,fp0
@@:
;'E'または'e'
exp:
	move.b	(a0)+,d7		;'E'の直後の文字
	move.b	(a6,d7.w),d7
	bgt	expHead			;'1'~'9'
	beq	expZrSp			;'0'
	addq.b	#-PL,d7
	bmi	err			;指数部の先頭が数字でも符号でもない
;指数部の符号
	ror.l	#1,d7
;
	move.b	(a0)+,d7		;指数部の符号の直後の文字
	move.b	(a6,d7.w),d7
	bgt	expHead			;'1'~'9'
	bmi	err			;指数部の符号の直後が数字でない
;指数部の先頭が0
expZrSp:
	move.b	(a0)+,d7		;'0'の次の文字
	move.b	(a6,d7.w),d7
	beq	expZrSp			;'0'をスキップする
	bmi	expChk			;指数部は0だった
;指数部の先頭の0以外の数字から
expHead:
	move.w	d7,d1
	move.b	(a0)+,d7		;指数部の上から2桁目
	move.b	(a6,d7.w),d7
	bmi	expEnd			;'0'~'9'以外
	mulu.w	#10,d1
	add.w	d7,d1
	move.b	(a0)+,d7		;指数部の上から3桁目
	move.b	(a6,d7.w),d7
	bmi	expEnd			;'0'~'9'以外
	mulu.w	#10,d1
	add.w	d7,d1
	move.b	(a0)+,d7		;指数部の上から4桁目
	move.b	(a6,d7.w),d7
	bpl	expErr			;指数部が4桁以上ならオーバーフローまたはアンダーフロー
;指数部終わり
expEnd:
	tst.l	d7
	bpl	@f			;指数部は正
	neg.w	d1			;指数部は負
@@:	add.w	d1,d0			;小数点以下の桁数分ずらす
	cmp.w	#512,d0
	bge	expOver			;512乗以上を取り除く
	cmp.w	#-512,d0
	ble	expUnder		;-512乗以下を取り除く
;指数部が0でなければ補正する
;<d4.w:指数部-小数点以下の桁数
expChk:
	tst.w	d0
	beq	intChk			;指数部が0なので整数チェックへ
	bmi	expLeft			;小数点を左へずらす
;小数点を右にずらす
	moveq.l	#$0F,d7
	and.w	d0,d7
	mulu.w	#12,d7
	fmul.x	(digit_1,pc,d7.w),fp0
	lsr.w	#4,d0
	beq	intChk			;整数チェックへ
	lsr.w	#1,d0
	bcc	@f
	fmul.d	#0f1E+16,fp0		;+16乗
@@:	beq	intChk			;整数チェックへ
	lsr.w	#1,d0
	bcc	@f
	fmul.d	#0f1E+32,fp0		;+32乗
@@:	beq	intChk			;整数チェックへ
	lsr.w	#1,d0
	bcc	@f
	fmul.d	#0f1E+64,fp0		;+64乗
@@:	beq	intChk			;整数チェックへ
	lsr.w	#1,d0
	bcc	@f
	fmul.d	#0f1E+128,fp0		;+128乗
@@:	beq	intChk			;整数チェックへ
	fmul.d	#0f1E+256,fp0		;+256乗
	bra	intChk			;整数チェックへ

;10の正のベキのテーブル
digit_1:
;  .rept %e,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
;	.dc.d	0f1E+%e
;  .endm
	.dc.x	!3FFF00008000000000000000	;10^0
	.dc.x	!40020000A000000000000000	;10^1
	.dc.x	!40050000C800000000000000	;10^2
	.dc.x	!40080000FA00000000000000	;10^3
	.dc.x	!400C00009C40000000000000	;10^4
	.dc.x	!400F0000C350000000000000	;10^5
	.dc.x	!40120000F424000000000000	;10^6
	.dc.x	!401600009896800000000000	;10^7
	.dc.x	!40190000BEBC200000000000	;10^8
	.dc.x	!401C0000EE6B280000000000	;10^9
	.dc.x	!402000009502F90000000000	;10^10
	.dc.x	!40230000BA43B74000000000	;10^11
	.dc.x	!40260000E8D4A51000000000	;10^12
	.dc.x	!402A00009184E72A00000000	;10^13
	.dc.x	!402D0000B5E620F480000000	;10^14
	.dc.x	!40300000E35FA931A0000000	;10^15

;10の負のベキのテーブル
digit_2:
;  .rept %e,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
;	.dc.d	0f1E-%e
;  .endm
	.dc.x	!3FFF00008000000000000000	;10^-0
	.dc.x	!3FFB0000CCCCCCCCCCCCCCCD	;10^-1
	.dc.x	!3FF80000A3D70A3D70A3D70A	;10^-2
	.dc.x	!3FF5000083126E978D4FDF3B	;10^-3
	.dc.x	!3FF10000D1B71758E219652B	;10^-4
	.dc.x	!3FEE0000A7C5AC471B478422	;10^-5
	.dc.x	!3FEB00008637BD05AF6C69B5	;10^-6
	.dc.x	!3FE70000D6BF94D5E57A42BB	;10^-7
	.dc.x	!3FE40000ABCC77118461CEFC	;10^-8
	.dc.x	!3FE1000089705F4136B4A596	;10^-9
	.dc.x	!3FDD0000DBE6FECEBDEDD5BD	;10^-10
	.dc.x	!3FDA0000AFEBFF0BCB24AAFE	;10^-11
	.dc.x	!3FD700008CBCCC096F5088CB	;10^-12
	.dc.x	!3FD30000E12E13424BB40E12	;10^-13
	.dc.x	!3FD00000B424DC35095CD80E	;10^-14
	.dc.x	!3FCD0000901D7CF73AB0ACD8	;10^-15

;小数点を左にずらす
expLeft:
	neg.w	d0
	moveq.l	#$0F,d7
	and.w	d0,d7
	mulu.w	#12,d7
	fmul.x	(digit_2,pc,d7.w),fp0
	lsr.w	#4,d0
	beq	intChk			;整数チェックへ
	lsr.w	#1,d0
	bcc	@f
	fmul.d	#0f1E-16,fp0		;-16乗
@@:	beq	intChk			;整数チェックへ
	lsr.w	#1,d0
	bcc	@f
	fmul.d	#0f1E-32,fp0		;-32乗
@@:	beq	intChk			;整数チェックへ
	lsr.w	#1,d0
	bcc	@f
	fmul.d	#0f1E-64,fp0		;-64乗
@@:	beq	intChk			;整数チェックへ
	lsr.w	#1,d0
	bcc	@f
	fmul.d	#0f1E-128,fp0		;-128乗
@@:	beq	intChk			;整数チェックへ
	fmul.d	#0f1E-256,fp0		;-256乗
	bra	intChk

intChk0:
;符号を付ける
	tst.l	d0
	bpl	@f
	fneg.x	fp0,fp0
@@:
;整数チェック
intChk:
	subq.l	#1,a0
	moveq.l	#-1,d2
	fmove.l	#$00000000,fpsr
	fmove.l	fp0,d3
	fmove.l	fpsr,d7
	and.w	#FPES_OPERR|FPES_OVFL|FPES_INEX2|FPES_INEX1,d7
	beq	@f
	moveq.l	#0,d2
	moveq.l	#0,d3
@@:
;返却値を作る
	fmove.l	#$00000000,fpsr
	fmove.d	fp0,-(sp)
	move.l	(sp)+,d0
	move.l	(sp)+,d1
	fmove.l	fpsr,d7
	and.b	#i|v|u|0|0|0|0|0,d7	;ivu00000
	bne	@f
	rts

@@:	add.b	d7,d7			;vu000000
	rol.b	#2,d7			;000000vu
	or.b	#0|0|0|0|C,d7		;000000vc
	rts

;指数部が範囲外
expErr:
	tst.l	d7			;指数部の符号を見る
	bpl	expOver			;オーバーフロー
;アンダーフロー
expUnder:
	subq.l	#1,a0
	moveq.l	#0,d0			;符号は付けない
	moveq.l	#0,d1
	moveq.l	#0,d2
	moveq.l	#0,d3
	moveq.l	#0|0|0|0|C,d7
	rts

;オーバーフロー
expOver:
	subq.l	#1,a0
	ftst.x	fp0			;仮数部が0のときはエラーにしない
	fbeq	@f
	clr.w	d0
	or.l	#$7FF00000,d0		;符号を付ける
	moveq.l	#0,d1
	moveq.l	#0,d2
	moveq.l	#0,d3
	moveq.l	#0|0|0|V|C,d7
	rts

@@:	moveq.l	#0,d0
	moveq.l	#0,d1
	moveq.l	#-1,d2
	moveq.l	#0,d3
	moveq.l	#0,d7
	rts

;----------------------------------------------------------------
;$FE23	__DTOS
;	8バイト浮動小数点数を文字列に変換します。
;	d0,d1は壊れます。
;<d0-d1:8バイト浮動小数点数
;<a0.l:変換された文字列の格納用バッファを指すポインタ
;>(a0):変換された文字列
fe_dtos::
	move.l	d2,-(sp)
	cmp.l	#$7FF00000,d0
	bge	1f
	cmp.l	#$FFF00000,d0
	bhs	1f
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
	bsr	dtos
	exit	d2

1:	bne	2f
	tst.l	d1
	bne	2f
	tst.l	d0
	bpl	@f
	move.b	#'-',(a0)+
@@:	move.l	#'#INF',(a0)+
	bra	3f

2:	move.l	#'#NAN',(a0)+
3:	clr.b	(a0)
	exit	d2

;----------------------------------------------------------------
;dtos
;浮動小数点数を全体の桁数を指定した浮動小数点表現または指数表現の文字列に変換する
;<a0.l:バッファの先頭
;<fp0:浮動小数点数(#INFや#NANは不可)
;>(a0):変換された文字列
;>a0.l:文字列の末尾の0のアドレス
;	負の値の場合は文字列の先頭にマイナス記号('-')が付加される
;	d2の桁数で表現できない場合は指数表現の文字列に変換する
;*a0,?d0-d2/fp0
dtos:
	moveq.l	#14,d2
	ftst.x	fp0
	fbeq	9f			;浮動小数点数が0
	fbgt	@f
	move.b	#'-',(a0)+
@@:	clr.b	(a0)+			;バッファの先頭または'-'の直後は0(番兵)
	bsr	ecvt
	movea.l	a0,a6			;最後の桁の次の位置
		suba.l	d2,a0
@@:	cmp.b	#'0',-(a6)		;0のときは番兵で止まる
	beq	@b
;<a6.l:'0'でない最後の桁の位置または番兵の位置
	cmpa.l	a0,a6
	blo	7f			;0だった(符号が必要なのでd1を壊す前に飛ぶこと)
	addq.l	#1,a6
;<a6.l:'0'でない最後の桁の次の位置
	move.l	a6,d1			;0でない最後の桁の次の位置
		sub.l	a0,d1		;下位の0を除いた桁数
;     ←── d1 ──→
;    a0              a6
;    ↓              ↓
;     ←───── d2 ─────→      d0
; -□XXXXXXXX000000×10
;    ↑
;-←・→+
;    d0
	cmp.l	d2,d0
	bgt	1f			;指数が大きすぎる(指数形式)
	tst.l	d0
	bgt	4f			;途中に小数点が入る(整数部.小数部)
;指数部が0以下(指数表現でなければ0.に続く)
	neg.l	d0			;0.の右側の0の数
		add.l	d0,d1		;0.の右側の桁数
;    ←─── d1 ───→
;       a0              a6
;       ↓              ↓
;    ←───── d2 ─────→
;0.00XXXXXXXX000000
;  → d0 ←
	cmp.l	d2,d1
	ble	5f			;先頭に0.00…を追加する(指数は不要)
;指数が小さすぎる(指数形式)
;<d1.l:有効な桁数
	move.b	(a0),(-1,a0)
		move.b	#'.',(a0)
	sub.l	d0,d1			;0でない部分の桁数
		adda.l	d1,a0		;最後の桁の右側
	subq.l	#1,d1
	bne	@f
	subq.l	#1,a0			;'.E'のとき'E'だけにする
@@:	move.b	#'E',(a0)+
		move.b	#'-',(a0)+
	bra	2f

;指数が大きすぎる(指数形式)
;<d1.l:有効な桁数
1:	move.b	(a0),(-1,a0)
		move.b	#'.',(a0)
	adda.l	d1,a0			;最後の桁の右側
		subq.l	#1,d1
	bne	@f
	subq.l	#1,a0			;'.E'のとき'E'だけにする
@@:		move.b	#'E',(a0)+
	move.b	#'+',(a0)+
;指数を10進4~3桁で書く
;<d0.l:指数(整数)
2:	subq.l	#1,d0			;0.1以上1未満を1以上10未満にする
	cmp.l	#1000,d0
	blo	2f
	move.l	#1000,d1
		moveq.l	#'0'-1,d7
@@:	addq.b	#1,d7
		sub.l	d1,d0
	bcc	@b
	add.l	d1,d0
		move.b	d7,(a0)+
;指数を10進3桁で書く
;<d0.l:指数(整数)
2:	moveq.l	#100,d1
		moveq.l	#'0'-1,d7
@@:	addq.b	#1,d7
		sub.l	d1,d0
	bcc	@b
	add.l	d1,d0
		move.b	d7,(a0)+
	moveq.l	#10,d1
		moveq.l	#'0'-1,d7
@@:	addq.b	#1,d7
		sub.l	d1,d0
	bcc	@b
	add.l	d1,d0
		move.b	d7,(a0)+
	add.b	#'0',d0
	move.b	d0,(a0)+
	clr.b	(a0)
	rts

;整数部がある
;<d0.l:整数部の桁数(≦d2)
;<d1.l:末尾の0を除いた桁数(≦d2,小数点を含まない)
4:	sub.l	d0,d1			;小数部の桁数
	ble	3f			;整数部のみ
;途中に小数点が入る(整数部.小数部)
@@:	move.b	(a0)+,(-2,a0)
		subq.l	#1,d0
	bne	@b
	move.b	#'.',(-1,a0)
		adda.l	d1,a0		;最後の桁の右側
	clr.b	(a0)
	rts

;整数部のみ
;<d0.l:桁数(≦d2)
3:
@@:	move.b	(a0)+,(-2,a0)
		subq.l	#1,d0
	bne	@b
	clr.b	-(a0)
	rts

;先頭に0.00…を追加する(指数は不要)
;    ←──── d1 ────→
;           a0              a6
;           ↓              ↓
;            ←───── d2 ─────→
;0.0000XXXXXXXX000000×10
;    ← d0 →
;<d0.l:0.の右側の0の数
;<d1.l:0.の右側の0でない最後の桁までの桁数
5:	sub.l	d0,d1			;0でない部分の桁数
;    ← d0 →←── d1 ──→
;           a0              a6
;           ↓              ↓
;            ←───── d2 ─────→
;0.0000XXXXXXXX000000
;          0.0000XXXXXXXX0
	lea.l	(1,a6,d0.l),a0
@@:	move.b	-(a6),(1,a6,d0.l)	;右にずらす
		subq.l	#1,d1
	bne	@b
	lea.l	(1,a6,d0.l),a6
		tst.l	d0
	beq	2f
1:	move.b	#'0',-(a6)
		subq.l	#1,d0
	bne	1b
2:	move.b	#'.',-(a6)
		move.b	#'0',-(a6)
	clr.b	(a0)
	rts

;すべての桁が0だった
;<d1.l:符号(0=正,1=負)
;<a0.l:番兵の次の位置
7:	subq.l	#1,a0			;番兵の位置
		suba.l	d1,a0		;負符号の分戻してバッファの先頭へ
;浮動小数点数が0のとき
9:	move.b	#'0',(a0)+
		clr.b	(a0)
	rts

;----------------------------------------------------------------
;$FE24	__ECVT
;	8バイト浮動小数点数を全体の桁数を指定して文字列に変換します。
;<d0-d1:8バイト浮動小数点数
;<d2.b:全体の桁数
;<a0.l:変換された文字列の格納用バッファを指すポインタ
;>d0.l:小数点の位置
;>d1.l:符号(0=正,1=負)
;>(a0):変換された文字列
fe_ecvt::
	move.l	d2,-(sp)
	and.l	#$000000FF,d2
	cmp.l	#$7FF00000,d0
	bge	9f
	cmp.l	#$FFF00000,d0
	bhs	9f
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
	move.l	a0,-(sp)		;a0を破壊しない
	bsr	ecvt
	movea.l	(sp)+,a0
	exit	d2

9:	bne	1f
	tst.l	d1
	bne	1f
	moveq.l	#0,d1
	tst.l	d0
	bpl	@f
	moveq.l	#1,d1
	subq.l	#1,d2			;純正は桁数が足りないと$00をいれようとする
	bcs	2f
	move.b	#'-',(a0)+
@@:	subq.l	#1,d2
	bcs	2f
	move.b	#'#',(a0)+
	subq.l	#1,d2
	bcs	2f
	move.b	#'I',(a0)+
	subq.l	#1,d2
	bcs	2f
	move.b	#'N',(a0)+
	subq.l	#1,d2
	bcs	2f
	move.b	#'F',(a0)+
	bra	2f

1:	moveq.l	#0,d1
	subq.l	#1,d2
	bcs	2f
	move.b	#'#',(a0)+
	subq.l	#1,d2
	bcs	2f
	move.b	#'N',(a0)+
	subq.l	#1,d2
	bcs	2f
	move.b	#'A',(a0)+
	subq.l	#1,d2
	bcs	2f
	move.b	#'N',(a0)+
2:	clr.b	(a0)
	move.l	#4,d0			;常に4
	exit	d2

;----------------------------------------------------------------
;ecvt
;浮動小数点数を全体の桁数を指定した浮動小数点表現の文字列に変換する
;<d2.l:全体の桁数(負数は不可)
;<a0.l:バッファの先頭
;<fp0:浮動小数点数(#INFや#NANは不可)
;>d0.l:10進指数部(浮動小数点数が0のときは1)
;>d1.l:符号(0=正,1=負)
;>(a0):変換された文字列(符号や小数点は含まない)
;>a0.l:文字列の末尾の0のアドレス
;*d0-d1/a0,?d2/d7/a6/fp0
ecvt:
	bsr	dexp			;d7/a6を破壊する
	ftst.x	fp0
	fbeq	9f			;浮動小数点数が0
;指定された桁数の文字列に変換する
	move.l	a0,-(sp)		;バッファの先頭
		move.l	d2,-(sp)	;桁数
	ble	2f
1:	fmul.s	#0f10,fp0
	fintrz.x	fp0,fp1
	fmove.l	fp1,d7
		add.b	#'0',d7		;'0'~'9'にする
	fsub.x	fp1,fp0
		move.b	d7,(a0)+
	subq.l	#1,d2
	bne	1b
2:
;四捨五入
	fcmp.s	#0f0.5,fp0
	fblt	3f			;次の桁が5未満なので切り捨てる
;繰り上げる
	move.l	(sp),d2			;桁数
	ble	2f
1:	addq.b	#1,-(a0)		;繰り上がり
		cmpi.b	#'9',(a0)
	bls	3f			;上の位に納まったので終わり
		move.b	#'0',(a0)	;上の位も溢れた
	subq.l	#1,d2
	bne	1b
2:
;最上位から繰り上がった
	addq.l	#1,d0			;指数部が1増える
		move.l	(sp),d2		;桁数
	ble	2f
	move.b	#'1',(a0)+		;先頭を1にする
	bra	4f
1:	move.b	#'0',(a0)+		;残りを0にする
4:	subq.l	#1,d2
	bne	1b
2:
;終わり
3:	move.l	(sp)+,d2		;桁数
		movea.l	(sp)+,a0	;バッファの先頭
	adda.l	d2,a0			;末尾の桁の次の位置
	clr.b	(a0)
	rts

;0のとき
9:	tst.l	d2
	ble	2f
1:	move.b	#'0',(a0)+		;d2+1個0を並べる
	subq.l	#1,d2
	bne	1b
2:	moveq.l	#1,d0			;10^1にする
	clr.b	(a0)
	rts

;----------------------------------------------------------------
;浮動小数点数を10進正規化する
;	fp0→(-1)^d1*fp0*10^d0(fp0は0または0.1以上1未満)
;<fp0:浮動小数点数(#INFや#NANは不可)
;>d0.l:10進指数部
;>d1.l:符号(0=正,1=負)
;>fp0:仮数部(0または0.1以上1未満)
;*d0-d1/fp0,?d7/a6
dexp:
	fmove.x	fp0,-(sp)
	moveq.l	#0,d1
		move.w	(sp),d0
	lea.l	(12,sp),sp
	bpl	@f
	fneg.x	fp0,fp0
		moveq.l	#1,d1
	and.w	#$7FFF,d0
@@:
;<d0.w:2進指数部+$3FFF(0~$7FFF)
	tst.w	d0
	beq	dexpZero		;絶対値が0
	sub.w	#$3FFF,d0
	bmi	dexpMinus		;絶対値が1未満
;絶対値が1以上
;<d0.w:2進指数部(0~$4000)
dexpPlus:
;2進指数部にlog10(2)を掛けて10進指数部を求める(大きめに出す)
	mulu.w	#19729,d0		;log10(2)*65536を繰り上げたもの
	clr.w	d0
	swap.w	d0
;<d0.w:10進指数部(0~4932,1だけ大きすぎることがある)
	move.l	d0,d7
;;;	beq	3f
	lea.l	(dexpMinusTable,pc),a6
1:	lsr.w	#1,d7
	bcc	2f
	fmul.x	(a6),fp0
2:	lea.l	(12,a6),a6
	bne	1b
3:
;10で割って0.1以上1未満にする
	fmul.x	dexpMinusTable,fp0	;0.1
	addq.l	#1,d0
;10進指数部が1だけ大きすぎたとき小さくなりすぎている
;誤差の修正
	fcmp.x	dexpMinusTable,fp0	;0.1
	fblt	dexpRight		;小さすぎる
	fcmp.s	#0f1,fp0
	fbge	dexpLeftOne		;大きすぎる
	rts

dexpRight:
	fmul.s	#0f10,fp0
		subq.l	#1,d0
	fcmp.x	dexpMinusTable,fp0	;0.1
	fblt	dexpRight
	rts

dexpLeftOne:
	fmul.x	dexpMinusTable,fp0	;0.1
		addq.l	#1,d0
	rts

;絶対値が0
dexpZero:
	fmove.s	#0f0,fp0		;念のため
	moveq.l	#0,d0
	moveq.l	#0,d1
	rts

;絶対値が1未満
;<d0.w:2進指数部(-$3FFF~-1)
dexpMinus:
	neg.w	d0
;<d0.w:2進指数部の符号を変えたもの(1~$3FFF)
;2進指数部の符号を変えたものにlog10(2)を掛けて10進指数部の符号を変えたものを求める(大きめに出す)
	mulu.w	#19729,d0		;log10(2)*65536を繰り上げたもの
	clr.w	d0
	swap.w	d0
;<d0.w:10進指数部の符号を変えたもの(0~4931,1だけ大きすぎることがある)
	move.l	d0,d7
;;;	beq	3f
	lea.l	(dexpPlusTable,pc),a6
1:	lsr.w	#1,d7
	bcc	2f
	fmul.x	(a6),fp0
2:	lea.l	(12,a6),a6
	bne	1b
3:
;10進指数部が1だけ大きすぎたとき大きくなりすぎている
;指数部の符号を反転する
	neg.l	d0
;誤差の修正
	fcmp.x	dexpMinusTable,fp0	;0.1
	fblt	dexpRightOne		;小さすぎる
	fcmp.s	#0f1,fp0
	fbge	dexpLeft		;大きすぎる
	rts

dexpRightOne:
	fmul.s	#0f10,fp0
		subq.l	#1,d0
	rts

dexpLeft:
	fmul.x	dexpMinusTable,fp0	;0.1
		addq.l	#1,d0
	fcmp.s	#0f1,fp0
	fbge	dexpLeft
	rts

;10^(2^n),n=0~12のテーブル
	.align	4
dexpPlusTable:
;  .irp %e,1,2,4,8,16,32,64,128,256,512,1024,2048,4096
;	.dc.x	0f1E+%e
;  .endm
	.dc.x	!40020000A000000000000000	;10^1
	.dc.x	!40050000C800000000000000	;10^2
	.dc.x	!400C00009C40000000000000	;10^4
	.dc.x	!40190000BEBC200000000000	;10^8
	.dc.x	!403400008E1BC9BF04000000	;10^16
	.dc.x	!406900009DC5ADA82B70B59E	;10^32
	.dc.x	!40D30000C2781F49FFCFA6D5	;10^64
	.dc.x	!41A8000093BA47C980E98CE0	;10^128
	.dc.x	!43510000AA7EEBFB9DF9DE8E	;10^256
	.dc.x	!46A30000E319A0AEA60E91C7	;10^512
	.dc.x	!4D480000C976758681750C17	;10^1024
	.dc.x	!5A9200009E8B3B5DC53D5DE5	;10^2048
	.dc.x	!75250000C46052028A20979B	;10^4096

;10^(-2^n),n=0~12のテーブル
	.align	4
dexpMinusTable:
;  .irp %e,1,2,4,8,16,32,64,128,256,512,1024,2048,4096
;	.dc.x	0f1E-%e
;  .endm
	.dc.x	!3FFB0000CCCCCCCCCCCCCCCD	;10^-1
	.dc.x	!3FF80000A3D70A3D70A3D70A	;10^-2
	.dc.x	!3FF10000D1B71758E219652C	;10^-4
	.dc.x	!3FE40000ABCC77118461CEFD	;10^-8
	.dc.x	!3FC90000E69594BEC44DE15B	;10^-16
	.dc.x	!3F940000CFB11EAD453994BA	;10^-32
	.dc.x	!3F2A0000A87FEA27A539E9A5	;10^-64
	.dc.x	!3E550000DDD0467C64BCE4A0	;10^-128
	.dc.x	!3CAC0000C0314325637A193A	;10^-256
	.dc.x	!395A00009049EE32DB23D21C	;10^-512
	.dc.x	!32B50000A2A682A5DA57C0BE	;10^-1024
	.dc.x	!256B0000CEAE534F34362DE4	;10^-2048
	.dc.x	!0AD80000A6DD04C8D2CE9FDE	;10^-4096

;----------------------------------------------------------------
;10進正規化された浮動小数点数の仮数部を指定された桁数の文字列にする
;	指定された桁数の数字の並びになる(符号や小数点は入らない)
;	指定された桁数の次の桁を四捨五入する
;	四捨五入の結果小数点が1桁ずれたとき、10進指数部を1増やす
;<d0.l:10進指数部
;<d2.l:桁数
;<a0.l:文字列を格納するアドレス
;<fp0:浮動小数点数(0または1以上10未満,#INFや#NANは不可)
;>d0.l:10進指数部
;>(a0):指定された桁数の文字列('0'~'9'の列)
;	小数点の位置は先頭の数字の右側
;	指定された桁数より後の領域は破壊しない
;?d7/fp0-fp1
dstr:
	move.l	a0,-(sp)
		move.l	d2,-(sp)
;指定された桁数の文字列に変換する
1:	fmul.s	#0f10,fp0		;100倍にしてテーブルを引いてもよいが、
	fintrz.x	fp0,fp1		;fmulは十分速いのでこのままにしておく
	fmove.l	fp1,d7
		add.b	#'0',d7		;'0'~'9'にする
	fsub.x	fp1,fp0
		move.b	d7,(a0)+
	subq.l	#1,d2
	bne	1b
;四捨五入
	fcmp.s	#0f0.5,fp0
	fblt	4f			;次の桁が5未満なので切り捨てる
;繰り上げる
	move.l	(sp),d2			;桁数
2:	addq.b	#1,-(a0)		;繰り上がり
		cmpi.b	#'9',(a0)
	bls	4f			;上の位に納まったので終わり
		move.b	#'0',(a0)	;上の位も溢れた
	subq.l	#1,d2
	bne	2b
;最上位から繰り上がった
	move.b	#'1',(a0)+
		move.l	(sp),d2		;桁数
	subq.l	#1,d2			;桁数-1
3:	move.b	#'0',(a0)+
		subq.l	#1,d2
	bne	3b
	addq.l	#1,d0			;最上位から繰り上がったので指数部が1増える
;終わり
4:	move.l	(sp)+,d2
		movea.l	(sp)+,a0
	rts

;----------------------------------------------------------------
;$FE25	__FCVT
;	8バイト浮動小数点数を小数点以下の桁数を指定して、文字列に変換します。
;<d0-d1:8バイト浮動小数点数
;<d2.b:小数点以下の桁数
;<a0.l:変換された文字列の格納用バッファを指すポインタ
;>d0.l:小数点の位置
;>d1.l:符号(0=正,1=負)
;>(a0):変換された文字列
fe_fcvt::
	move.l	d2,-(sp)
	and.l	#$000000FF,d2
	cmp.l	#$7FF00000,d0
	bge	9f
	cmp.l	#$FFF00000,d0
	bhs	9f
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
	move.l	a0,-(sp)		;a0を破壊しない
	bsr	fcvt
	movea.l	(sp)+,a0
	exit	d2

9:	bne	1f
	tst.l	d1
	bne	1f
	moveq.l	#0,d1
	tst.l	d0
	bpl	@f
	moveq.l	#1,d1
	move.b	#'-',(a0)+
@@:	move.l	#'#INF',(a0)+		;奇数アドレスの可能性がある
					;純正は桁数が足りないと$00に指数を付けて結局はみ出す
	bra	2f

1:	moveq.l	#0,d1
	move.l	#'#NAN',(a0)+		;奇数アドレスの可能性がある
2:	clr.b	(a0)
	move.l	#4,d0			;常に4
	exit	d2

;----------------------------------------------------------------
;fcvt
;浮動小数点数を小数部の桁数を指定した浮動小数点表現の文字列に変換する
;<d2.l:小数部の桁数
;<a0.l:変換された文字列の格納用バッファを指すポインタ
;<fp0:浮動小数点数
;>d0.l:10進指数部
;>d1.l:符号(0=正,1=負)
;>(a0):変換された文字列(符号や小数点は含まない)
;	整数部は何桁でも展開する
;	0ではないが絶対値が小さすぎて指定した範囲内に0しかないときヌル文字列になる
;	0のときは0.xxxx*10^1になる
;>a0.l:文字列の末尾の0のアドレス
;*a0,?d0-d2/d7/fp0
fcvt:
	bsr	dexp			;d7/a6を破壊する
	ftst.x	fp0
	fbeq	fcvtZero
	tst.l	d0
	blt	4f			;指数部が負
;指数部が0以上
	add.l	d0,d2			;全体の桁数
;文字列に変換する
	move.l	a0,-(sp)
		move.l	d2,-(sp)	;全体の桁数
	beq	2f
1:	fmul.s	#0f10,fp0
	fintrz.x	fp0,fp1
	fmove.l	fp1,d7
		add.b	#'0',d7		;'0'~'9'にする
	fsub.x	fp1,fp0
		move.b	d7,(a0)+
	subq.l	#1,d2
	bne	1b
2:
;四捨五入
	fcmp.s	#0f0.5,fp0
	fblt	3f			;次の桁が5未満なので切り捨てる
;繰り上げる
	move.l	(sp),d2			;全体の桁数
	beq	2f
1:	addq.b	#1,-(a0)		;繰り上がり
		cmpi.b	#'9',(a0)
	bls	3f			;上の位に納まったので終わり
		move.b	#'0',(a0)	;上の位も溢れた
	subq.l	#1,d2
	bne	1b
2:
;最上位から繰り上がった
	move.b	#'1',(a0)+		;整数部なので無条件に書く
		move.l	(sp),d2		;全体の桁数(先頭の1を含まない)
	beq	2f
1:	move.b	#'0',(a0)+
		subq.l	#1,d2
	bne	1b
2:	addq.l	#1,d0			;最上位から繰り上がったので整数部が1桁増える
		addq.l	#1,(sp)		;整数部が1桁増えるので全体の桁数も1桁増える
;終わり
3:	move.l	(sp)+,d2		;全体の桁数
		movea.l	(sp)+,a0	;バッファの先頭
	adda.l	d2,a0			;末尾の桁の次の位置
9:	clr.b	(a0)
	rts

;指数部が負
4:	add.l	d0,d2			;残る桁数
;	bmi	9b			;繰り上がっても残らない
					;ここでジャンプしてしまうと繰り上がることによる
					;指数の補正が正しく行われなくなる
;文字列に変換する
	move.l	a0,-(sp)
		move.l	d2,-(sp)	;残る桁数
	ble	2f
1:	fmul.s	#0f10,fp0
	fintrz.x	fp0,fp1
	fmove.l	fp1,d7
		add.b	#'0',d7		;'0'~'9'にする
	fsub.x	fp1,fp0
		move.b	d7,(a0)+
	subq.l	#1,d2
	bne	1b
2:
;四捨五入
	fcmp.s	#0f0.5,fp0
	fblt	3f			;次の桁が5未満なので切り捨てる
;繰り上げる
	move.l	(sp),d2			;残る桁数
	ble	2f
1:	addq.b	#1,-(a0)		;繰り上がり
		cmpi.b	#'9',(a0)
	bls	3f			;上の位に納まったので終わり
		move.b	#'0',(a0)	;上の位も溢れた
	subq.l	#1,d2
	bne	1b
2:
;最上位から繰り上がった
	move.l	(sp),d2			;残る桁数(繰り上げて書いた1を含まない)
	blt	2f
	move.b	#'1',(a0)+
		tst.l	d2
	beq	2f
1:	move.b	#'0',(a0)+
		subq.l	#1,d2
	bne	1b
2:	addq.l	#1,d0			;最上位から繰り上がった
		addq.l	#1,(sp)		;残る桁数が1桁増える
;終わり
3:	move.l	(sp)+,d2		;残る桁数
		movea.l	(sp)+,a0	;小数部の最初の0以外の数字の位置
;	tst.l	d2
	ble	@f
	adda.l	d2,a0			;末尾の桁の次の位置
@@:	clr.b	(a0)
	rts

fcvtZero:
@@:	move.b	#'0',(a0)+		;d2+1個0を並べる
	subq.l	#1,d2
	bcc	@b
	moveq.l	#1,d0			;10^1にする
	clr.b	(a0)
	rts

;----------------------------------------------------------------
;$FE26	__GCVT
;	8バイト浮動小数点数を全体の桁数を指定した浮動小数点表現または指数表現の文字列に
;	変換します。
;<d0-d1:8バイト浮動小数点数
;<d2.b:全体の桁数
;<a0.l:変換された文字列の格納用バッファを指すポインタ
;>(a0):変換された文字列
;	負の値の場合は文字列の先頭にマイナス記号('-')が付加されます。
;	d2の桁数で表現できない場合に、指数表現の文字列に変換します。
fe_gcvt::
	move.l	d2,-(sp)
	and.l	#$000000FF,d2
	cmp.l	#$7FF00000,d0
	bge	9f
	cmp.l	#$FFF00000,d0
	bhs	9f
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
	bsr	gcvt
	exit	d2

9:	bne	1f
	tst.l	d1
	bne	1f
	moveq.l	#0,d1
	tst.l	d0
	bpl	@f
	moveq.l	#1,d1
	move.b	#'-',(a0)+
@@:	move.l	#'#INF',(a0)+		;奇数アドレスの可能性がある
					;純正は桁数が足りないと$00に指数を付けて結局はみ出す
	bra	2f

1:	moveq.l	#0,d1
	move.l	#'#NAN',(a0)+		;奇数アドレスの可能性がある
2:	clr.b	(a0)
	move.l	#4,d0			;常に4
	exit	d2

;----------------------------------------------------------------
;gcvt
;浮動小数点数を全体の桁数を指定した浮動小数点表現または指数表現の文字列に変換する
;<d2.l:全体の桁数(負数は不可,符号や小数点は含まない,ただし0.0xxxとなるときは0.を含む)
;<a0.l:バッファの先頭
;<fp0:浮動小数点数(#INFや#NANは不可)
;>(a0):変換された文字列
;>a0.l:文字列の末尾の0のアドレス
;	負の値の場合は文字列の先頭にマイナス記号('-')が付加される
;	d2の桁数で表現できない場合は指数表現の文字列に変換する
;*a0,?d0-d2/d7/a6/fp0
gcvt:
	ftst.x	fp0
	fbeq	9f			;浮動小数点数が0
	fbgt	@f
	move.b	#'-',(a0)+
@@:	clr.b	(a0)+			;バッファの先頭または'-'の直後は0(番兵)
	bsr	ecvt			;d0-d2/d7/a6を破壊する,a0は末尾の0の位置
	movea.l	a0,a6			;最後の桁の次の位置
		suba.l	d2,a0
@@:	cmp.b	#'0',-(a6)		;0のときは番兵で止まる
	beq	@b
;<a6.l:'0'でない最後の桁の位置または番兵の位置
	cmpa.l	a0,a6
	blo	7f			;0だった(符号が必要なのでd1を壊す前に飛ぶこと)
	addq.l	#1,a6
;<a6.l:'0'でない最後の桁の次の位置
	move.l	a6,d1			;0でない最後の桁の次の位置
		sub.l	a0,d1		;下位の0を除いた桁数
;     ←── d1 ──→
;    a0              a6
;    ↓              ↓
;     ←───── d2 ─────→      d0
; -□XXXXXXXX000000×10
;    ↑
;-←・→+
;    d0
	cmp.l	d2,d0
	bgt	1f			;指数が大きすぎる(指数形式)
	tst.l	d0
	bgt	4f			;途中に小数点が入る(整数部.小数部)
;指数部が0以下(指数表現でなければ0.に続く)
	beq	@f
	subq.l	#2,d2
@@:	neg.l	d0			;0.の右側の0の数
		add.l	d0,d1		;0.の右側の桁数
;d0=0のとき
;    ←── d1 ──→
;   a0              a6
;   ↓              ↓
;    ←───── d2 ─────→
;0.XXXXXXXX000000
;  →←
;   d0
;d0>0のとき
;    ←─── d1 ───→
;       a0              a6
;       ↓              ↓     2
;    ←──── d2 ────→←→
;0.00XXXXXXXX000000
;  → d0 ←
	cmp.l	d2,d1
	ble	5f			;先頭に0.00…を追加する(指数は不要)
;指数が小さすぎる(指数形式)
;<d1.l:有効な桁数
	move.b	(a0),(-1,a0)
		move.b	#'.',(a0)
	sub.l	d0,d1			;0でない部分の桁数
		adda.l	d1,a0		;最後の桁の右側
	move.b	#'E',(a0)+
		move.b	#'-',(a0)+
	bra	2f

;指数が大きすぎる(指数形式)
;<d1.l:有効な桁数
1:	move.b	(a0),(-1,a0)
		move.b	#'.',(a0)
	adda.l	d1,a0			;最後の桁の右側
		move.b	#'E',(a0)+
	move.b	#'+',(a0)+
;指数を10進4~3桁で書く
;<d0.l:指数(整数)
2:	subq.l	#1,d0			;0.1以上1未満を1以上10未満にする
		cmp.l	#1000,d0
	blo	2f
	move.l	#1000,d1
		moveq.l	#'0'-1,d7
@@:	addq.b	#1,d7
		sub.l	d1,d0
	bcc	@b
	add.l	d1,d0
		move.b	d7,(a0)+
;指数を10進3桁で書く
;<d0.l:指数(整数)
2:	moveq.l	#100,d1
		moveq.l	#'0'-1,d7
@@:	addq.b	#1,d7
		sub.l	d1,d0
	bcc	@b
	add.l	d1,d0
		move.b	d7,(a0)+
	moveq.l	#10,d1
		moveq.l	#'0'-1,d7
@@:	addq.b	#1,d7
		sub.l	d1,d0
	bcc	@b
	add.l	d1,d0
		move.b	d7,(a0)+
	add.b	#'0',d0
		move.b	d0,(a0)+
	clr.b	(a0)
	rts

;整数部がある
;<d0.l:整数部の桁数(≦d2)
;<d1.l:末尾の0を除いた桁数(≦d2,小数点を含まない)
4:	sub.l	d0,d1			;小数部の桁数
	ble	3f			;整数部のみ
;途中に小数点が入る(整数部.小数部)
@@:	move.b	(a0)+,(-2,a0)
		subq.l	#1,d0
	bne	@b
	move.b	#'.',(-1,a0)
		adda.l	d1,a0		;最後の桁の右側
	clr.b	(a0)
	rts

;整数部のみ
;<d0.l:桁数(≦d2)
3:	cmp.l	d2,d0
	beq	3f			;小数点は入り切らない
;整数部のみだが小数点を付ける
@@:	move.b	(a0)+,(-2,a0)
		subq.l	#1,d0
	bne	@b
	move.b	#'.',(-1,a0)
		clr.b	(a0)
	rts

;整数部のみで小数点は入り切らない
3:
@@:	move.b	(a0)+,(-2,a0)
		subq.l	#1,d0
	bne	@b
	clr.b	-(a0)
	rts

;先頭に0.00…を追加する(指数は不要)
;    ←──── d1 ────→
;           a0              a6
;           ↓              ↓
;            ←───── d2 ─────→
;0.0000XXXXXXXX000000×10
;    ← d0 →
;<d0.l:0.の右側の0の数
;<d1.l:0.の右側の0でない最後の桁までの桁数
5:	sub.l	d0,d1			;0でない部分の桁数
;    ← d0 →←── d1 ──→
;           a0              a6
;           ↓              ↓
;            ←───── d2 ─────→
;0.0000XXXXXXXX000000
;          0.0000XXXXXXXX0
	lea.l	(1,a6,d0.l),a0
@@:	move.b	-(a6),(1,a6,d0.l)	;右にずらす
		subq.l	#1,d1
	bne	@b
	lea.l	(1,a6,d0.l),a6
		tst.l	d0
	beq	2f
1:	move.b	#'0',-(a6)
		subq.l	#1,d0
	bne	1b
2:	move.b	#'.',-(a6)
		move.b	#'0',-(a6)
	clr.b	(a0)
	rts

;すべての桁が0だった
;<d1.l:符号(0=正,1=負)
;<a0.l:番兵の次の位置
7:	subq.l	#1,a0			;番兵の位置
		suba.l	d1,a0		;負符号の分戻してバッファの先頭へ
;浮動小数点数が0のとき
9:	move.b	#'0',(a0)+
		subq.l	#1,d2
	ble	@f
	move.b	#'.',(a0)+
@@:	clr.b	(a0)
	rts

;----------------------------------------------------------------
;$FE28	__DTST
;	8バイト浮動小数点数と0の比較をします。
;<d0-d1:8バイト浮動小数点数
;>z-flag:eq=0
;>n-flag:mi=負
fe_dtst::
	move.l	d0,d7
	or.w	d1,d7
	swap.w	d1
	or.w	d1,d7
	swap.w	d1
	tst.l	d7
	exit	ccr

;----------------------------------------------------------------
;$FE29	__DCMP
;	8バイト浮動小数点数どうしの比較をします。
;<d0-d1:被比較数
;<d2-d3:比較数
;	被比較数から比較数を減算した結果にしたがってセットされます。
;>n-flag:mi=負
;>z-flag:eq=0
;>c-flag:cs=ボローが発生した
;	被比較数が比較数より大きいとき	cc,ne,pl
;	被比較数が比較数と等しいとき	cc,eq,pl
;	被比較数が比較数より小さいとき	cs,ne,mi
fe_dcmp::
	tst.l	d0
	bmi	1f
	tst.l	d2
	bmi	2f
	cmp.l	d2,d0
	bne	@f
	cmp.l	d3,d1
@@:	exit	ccr

1:	tst.l	d2
	bpl	3f
	cmp.l	d0,d2
	bne	@f
	cmp.l	d1,d3
@@:	exit	ccr

2:	exit	_

3:	exit	C,N

;----------------------------------------------------------------
;$FE2A	__DNEG
;	8バイト浮動小数点数の符号を反転します。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
fe_dneg::
	tst.l	d0
	beq	@f
	bchg.l	#31,d0
@@:	exit

;----------------------------------------------------------------
;$FE2B	__DADD
;	8バイト浮動小数点数どうしの加算をします。
;<d0-d1:被加算数
;<d2-d3:加算数
;>d0-d1:演算結果
;>c-flag:cs=エラー
;>v-flag:(cs)vs=オーバーフロー,(cs)vc=アンダーフロー
fe_dadd::
	fmove.l	#$00000000,fpsr
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
		move.l	d3,-(sp)
	move.l	d2,-(sp)
	fadd.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fmove.d	fp0,-(sp)
	fmove.l	fpsr,d7
	and.b	#i|v|u|0|0|0|0|0,d7	;ivu00000
	bne	@f
	exit	d0,d1

@@:	add.b	d7,d7			;vu000000
	rol.b	#2,d7			;000000vu
	or.b	#0|0|0|0|C,d7		;000000vc
	exit	D7,d0,d1

;----------------------------------------------------------------
;$FE2C	__DSUB
;	8バイト浮動小数点数どうしの減算をします。
;<d0-d1:被減算数
;<d2-d3:減算数
;>d0-d1:演算結果
;>c-flag:cs=エラー
;>v-flag:(cs)vs=オーバーフロー,(cs)vc=アンダーフロー
fe_dsub::
	fmove.l	#$00000000,fpsr
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
		move.l	d3,-(sp)
	move.l	d2,-(sp)
	fsub.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fmove.d	fp0,-(sp)
	fmove.l	fpsr,d7
	and.b	#i|v|u|0|0|0|0|0,d7	;ivu00000
	bne	@f
	exit	d0,d1

@@:	add.b	d7,d7			;vu000000
	rol.b	#2,d7			;000000vu
	or.b	#0|0|0|0|C,d7		;000000vc
	exit	D7,d0,d1

;----------------------------------------------------------------
;$FE2D	__DMUL
;	8バイト浮動小数点数どうしの乗算をします。
;<d0-d1:被乗数
;<d2-d3:乗数
;>d0-d1:演算結果
;>c-flag:cs=エラー
;>v-flag:(cs)vs=オーバーフロー,(cs)vc=アンダーフロー
fe_dmul::
	fmove.l	#$00000000,fpsr
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
		move.l	d3,-(sp)
	move.l	d2,-(sp)
	fmul.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fmove.d	fp0,-(sp)
	fmove.l	fpsr,d7
	and.b	#i|v|u|0|0|0|0|0,d7	;ivu00000
	bne	@f
	exit	d0,d1

@@:	add.b	d7,d7			;vu000000
	rol.b	#2,d7			;000000vu
	or.b	#0|0|0|0|C,d7		;000000vc
	exit	D7,d0,d1

;----------------------------------------------------------------
;$FE2E	__DDIV
;	8バイト浮動小数点数どうしの除算をします。
;<d0-d1:被除数
;<d2-d3:除数
;>d0-d1:演算結果
;>c-flag:cs=エラー
;>z-flag:(cs)eq=0で割った
;>v-flag:(cs,ne)vs=オーバーフロー,(cs,ne)vc=アンダーフロー
fe_ddiv::
	fmove.l	#$00000000,fpsr
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
		move.l	d3,-(sp)
	move.l	d2,-(sp)
	fdiv.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fmove.d	fp0,-(sp)
	fmove.l	fpsr,d7
	and.b	#i|v|u|z|0|0|0|0,d7	;ivuz0000
	bne	@f
	exit	d0,d1

@@:	add.b	d7,d7			;vuz00000
	rol.b	#2,d7			;z00000vu
	bpl	@f
	addq.b	#4,d7			;z0000zvu
@@:	or.b	#0|0|0|0|C,d7		;z0000zvc
	exit	D7,d0,d1

;----------------------------------------------------------------
;$FE2F	__DMOD
;	8バイト浮動小数点数どうしの剰余を求めます。
;<d0-d1:被除数
;<d2-d3:除数
;>d0-d1:演算結果
;>c-flag:cs=エラー
;>z-flag:(cs)eq=0で割った
;>v-flag:(cs,ne)vs=有効数字の範囲外,(cs,ne)vc=アンダーフロー
fe_dmod::
	move.l	d2,d7
	add.l	d7,d7
	or.l	d3,d7
	beq	1f
	fmove.l	#$00000000,fpsr
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
		move.l	d3,-(sp)
	move.l	d2,-(sp)
	fmod.d	(sp)+,fp0		;エミュレーション
	fmove.d	fp0,-(sp)
	fmove.l	fpsr,d7
	and.b	#i|v|u|z|0|0|0|0,d7	;ivuz0000
	bne	@f
	exit	_,d0,d1

@@:	add.b	d7,d7			;vuz00000
	rol.b	#2,d7			;z00000vu
	bpl	@f
	addq.b	#4,d7			;z0000zvu
@@:	or.b	#0|0|0|0|C,d7		;z0000zvc
	exit	D7,d0,d1

1:	move.l	#$7FFFFFFF,d0
	moveq.l	#$FFFFFFFF,d1
	exit	C,Z

;----------------------------------------------------------------
;$FE30	__DABS
;	8バイト浮動小数点数の絶対値を求めます。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
fe_dabs::
	bclr.l	#31,d0
	exit

;----------------------------------------------------------------
;$FE31	__DCEIL
;	8バイト浮動小数点数と等しいか、それ以上の最小の整数を返します。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
fe_dceil::
	fmove.l	fpcr,d7
	fmove.l	#FPRM_RP,fpcr
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fint.d	(sp)+,fp0
	fmove.d	fp0,-(sp)
	fmove.l	d7,fpcr
	exit	d0,d1

;----------------------------------------------------------------
;$FE32	__DFIX
;	8バイト浮動小数点数の整数部を求めます。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
fe_dfix::
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fintrz.d	(sp)+,fp0
	fmove.d	fp0,-(sp)
	exit	d0,d1

;----------------------------------------------------------------
;$FE33	__DFLOOR
;	8バイト浮動小数点数と等しいかまたはそれより小さい最大の整数を返します。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
fe_dfloor::
	fmove.l	fpcr,d7
	fmove.l	#FPRM_RM,fpcr
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fint.d	(sp)+,fp0
	fmove.d	fp0,-(sp)
	fmove.l	d7,fpcr
	exit	d0,d1

;----------------------------------------------------------------
;$FE34	__DFRAC
;	8バイト浮動小数点数の小数部を求めます。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
;	整数部分を0にする(intrzを引く)
fe_dfrac::
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
	fintrz.x	fp0,fp1
	fsub.x	fp1,fp0
	fmove.d	fp0,-(sp)
	exit	d0,d1

;----------------------------------------------------------------
;$FE35	__DSGN
;	8バイト浮動小数点数が正か負か0かを調べます。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:結果(8バイト浮動小数点数)
;	正なら+1、負なら-1、0なら0を返します。
fe_dsgn::
	add.l	d0,d0
	beq	2f
1:	move.l	#$3FF00000<<1,d0
	roxr.l	#1,d0
	moveq.l	#0,d1
	exit

2:	tst.l	d1
	bne	1b
	moveq.l	#0,d0
		moveq.l	#0,d1
	exit

;----------------------------------------------------------------
;$FE36	__SIN
;	角度(ラジアン単位)を与えて正弦(sin)を計算します。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
;	|X|<=π/4としてから
;	{(-1)^(n-1)/(2n-1)!}X^(2n-1)が0になるまで加える
fe_sin::
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fpsp	sin
	fmove.d	fp0,-(sp)
		tst.b	d7
	bmi	@f
	exit	d0,d1

@@:	exit	C,d0,d1

;----------------------------------------------------------------
;$FE37	__COS
;	角度(ラジアン単位)を与えて余弦(cos)を計算します。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
;	|X|<=π/4としてから
;	{(-1)^n/(2n)!}X^2nが0になるまで加える
fe_cos::
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fpsp	cos
	fmove.d	fp0,-(sp)
		tst.b	d7
	bmi	@f
	exit	d0,d1

@@:	exit	C,d0,d1

;----------------------------------------------------------------
;$FE38	__TAN
;	角度(ラジアン単位)を与えて正接(tan)を計算します。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
;>c-flag:cs=エラー(引数が((2n+1)/2)π(n:整数))
;	sin/cos
fe_tan::
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fpsp	tan
	fmove.d	fp0,-(sp)
		tst.b	d7
	bmi	@f
	exit	d0,d1

@@:	exit	C,d0,d1

;----------------------------------------------------------------
;$FE39	__ATAN
;	逆正接(atan)を計算します。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果(ラジアン単位)
;	X>1のときπ/2-atan(1/X)
;	X>1/2のときatan(X)=atan(1/2)+atan(2X-1/(X+2))
;	X>1/4のときatan(X)=atan(1/4)+atan(4X-1/(X+4))
;	X>1/8のときatan(X)=atan(1/4)-atan(1-4X/(X+4))
;	X=1のときπ/4
;	{(-1)^n}X^(2n+1)/(2n+1)が0になるまで加える
fe_atan::
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fpsp	atan
	fmove.d	fp0,-(sp)
		tst.b	d7
	bmi	@f
	exit	d0,d1

@@:	exit	C,d0,d1

;----------------------------------------------------------------
;$FE3A	__LOG
;	自然対数(log)を計算します。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
;>c-flag:cs=エラー(引数が0または負)
;>z-flag:(cs)eq=引数が0(log 0)
fe_log::
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fpsp	logn
	fmove.d	fp0,-(sp)
		tst.b	d7
	bmi	@f
	exit	d0,d1

@@:	exit	C,d0,d1

;----------------------------------------------------------------
;$FE3B	__EXP
;	指数関数(e^x)を計算します。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
;>c-flag:cs=エラー(オーバーフロー)
;	0<=X<logn(2)のときX^n/n!が0になるまで加える
;	X>=logn(2)のときX=n*logn(2)±Y(nは整数,0<Y<log(2)/2)でexp(Y)を求めnビットずらす
fe_exp::
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fpsp	etox
	fmove.d	fp0,-(sp)
		tst.b	d7
	bmi	@f
	exit	d0,d1

@@:	exit	C,d0,d1

;----------------------------------------------------------------
;$FE3C	__SQR
;	平方根を計算します。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
;>c-flag:cs=エラー(引数が負)
fe_sqr::
	tst.l	d0
	bmi	9f
	fmove.l	#$00000000,fpsr
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fsqrt.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fmove.d	fp0,-(sp)
	fmove.l	fpsr,d7
	and.b	#i|v|u|0|0|0|0|0,d7	;ivu00000
	bne	@f
	exit	d0,d1

@@:	add.b	d7,d7			;vu000000
	rol.b	#2,d7			;000000vu
	or.b	#0|0|0|0|C,d7		;000000vc
	exit	D7,d0,d1

9:	exit	C

;----------------------------------------------------------------
;$FE3D	__PI
;	円周率を8バイト浮動小数点数の範囲内で返します。
;>d0-d1:演算結果
fe_pi::
	move.l	#$400921FB,d0
		move.l	#$54442D18,d1
	exit

;----------------------------------------------------------------
;$FE3E	__NPI
;	円周率と8バイト浮動小数点数の積(xπ)を計算します。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
;>c-flag:cs=エラー(オーバーフロー)
fe_npi::
	fmove.l	#$00000000,fpsr
	fmove.x	pi(pc),fp0		
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmul.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fmove.d	fp0,-(sp)
	fmove.l	fpsr,d7
	and.b	#i|v|u|0|0|0|0|0,d7	;ivu00000
	bne	@f
	exit	d0,d1

@@:	add.b	d7,d7			;vu000000
	rol.b	#2,d7			;000000vu
	or.b	#0|0|0|0|C,d7		;000000vc
	exit	D7,d0,d1

;----------------------------------------------------------------
;$FE3F	__POWER
;	べき乗(X^y)を計算します。
;<d0-d1:被べき乗数
;<d2-d3:指数
;>d0-d1:演算結果
;>c-flag:cs=エラー
;>v-flag:(cs)vs=オーバーフロー,(cs)vc=アンダーフロー
fe_power::
	bsr	power
	exit	ccr

power:
	movem.l	d0-d1,-(sp)
	fmove.l	#$00000000,fpsr
	flogn.d	(sp),fp0		;エミュレーション
					;fp0=ln(x)
	add.l	d0,d0
	cmpi.l	#$FFFFFFFE,d0
	beq	power_nan_y
	move.l	d2,d0
	add.l	d0,d0
	beq	power_x_0
	cmpi.l	#$FFE00000,d0
	bcc	power_x_infnan
	move.l	(sp),d0
	add.l	d0,d0
	beq	power_0_y
	bcs	power_minusnum_y
	movem.l	d2-d3,(sp)
	fmul.d	(sp),fp0		;fp0=ln(x)*y
	fetox.x	fp0			;エミュレーション
					;fp0=e^(ln(x)*y)=(e^ln(x))^y=x^y
	fmove.d	fp0,(sp)		;x^y
	fmove.l	fpsr,d0
	and.w	#FPAE_IOP|FPAE_OVFL|FPAE_DZ,d0
	beq	~0023FA
	add.b	d0,d0
	add.b	d0,d0
	bcc	~0023F6
	addq.b	#1,d0
~0023F6:
	add.b	d0,d0
	addq.b	#1,d0
~0023FA:
	move.w	d0,ccr
	movem.l	(sp)+,d0-d1
	rts

power_nan_y:
~002402:
	move.l	(sp),d0
	addq.l	#8,sp
	move.w	#$0000,ccr
	rts

power_x_infnan:
~00240C:
	beq	power_x_inf
	move.l	d2,d0
	move.l	d3,d1
	addq.l	#8,sp
	move.w	#$0000,ccr
	rts

power_x_inf:
~00241A:
	move.l	(sp),d0
	add.l	d0,d0
	beq	power_0_inf
	cmp.l	#$FFE00000,d0
	beq	power_inf_inf
	tst.l	d2
	bmi	power_x_minusinf
power_x_plusinf:
~00242E:
	move.l	(sp),d0
	and.l	#$80000000,d0
	or.l	#$7FF00000,d0
	moveq.l	#$00,d1
	addq.l	#8,sp
	move.w	#$0000,ccr
	rts

power_inf_inf:
~002446:
	tst.l	d2
	bpl	power_x_plusinf
	move.l	(sp),d0
	or.l	#$7FFFFFFF,d0
	moveq.l	#$FF,d1
	addq.l	#8,d0
	move.w	#$0000,ccr
	rts

power_x_0:
~00245C:
	move.l	#$3FF00000,d0
	moveq.l	#$00,d1
	addq.l	#8,sp
	move.w	#$0000,ccr
	rts

power_x_minusinf:
~00246C:
	tst.l	d0
	bmi	power_0_inf
power_0_y:
~002472:
	moveq.l	#$00,d0
	moveq.l	#$00,d1
	addq.l	#8,sp
	move.w	#$0000,ccr
	rts

power_minusnum_y:
~00247E:
	move.l	d2,d0
	move.l	d3,d1
;	bsr	fe_dfrac		;d0-d1=frac(y)
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
	fintrz.x	fp0,fp1
	fsub.x	fp1,fp0
	fmove.d	fp0,-(sp)
	movem.l	(sp)+,d0-d1
;
	add.l	d0,d0
	or.l	d0,d1
	bne	power_minusnum_notint
	fmove.l	#$00000000,fpsr
	fmove.d	(sp),fp1		;fp1=x
	movem.l	d2-d3,(sp)
	fmove.d	(sp),fp0		;fp0=y
	fmove.l	fp0,d0			;d0=int(y)
	tst.l	d0
	beq	power_x_0
	bpl	~0024B8			;y>0
					;y<0
	fmove.x	one(pc),fp0		;fp0=1
	fdiv.x	fp1,fp0			;fp0=1/x
	fmove.x	fp0,fp1			;fp1=1/x
	neg.l	d0			;x^(-y)=(1/x)^y
~0024B8:
	fmove.x	one(pc),fp0		;fp0=1
~0024BC:
	lsr.l	#1,d0
	bcc	~0024C8
	fmul.x	fp1,fp0
	tst.l	d0			;←いらないと思う
	beq	~0024CE
~0024C8:
	fmul.x	fp1,fp1
	bra	~0024BC

~0024CE:
	fmove.d	fp0,(sp)
	fmove.l	fpsr,d0
	and.w	#FPAE_IOP|FPAE_OVFL|FPAE_UNFL|FPAE_DZ,d0
	beq	~0024EC
	add.b	d0,d0
	add.b	d0,d0
	bcc	~0024E4
	addq.b	#1,d0
~0024E4:
	add.b	d0,d0
	bpl	~0024EA
	addq.b	#4,d0
~0024EA:
	addq.b	#1,d0
~0024EC:
	move.w	d0,ccr
	movem.l	(sp)+,d0-d1
	rts

power_0_inf:
power_minusnum_notint:
~0024F4:
	move.l	#$7FFFFFFF,d0
	moveq.l	#$FF,d1
	addq.l	#8,sp
	move.w	#SRU_C,ccr
	rts

;----------------------------------------------------------------
;$FE40	__RND
;	8バイト浮動小数点数の乱数を返します。
;>d0-d1:8バイト浮動小数点数の乱数(0以上1未満)
fe_rnd::
	bsr	rnd
	exit

rnd::
	bsr	rnd_long
	move.l	d0,d1
	bsr	rnd_long
	andi.l	#$001FFFFF,d0
	move.w	#$1FF0,d7
	bra	2f

1:	add.l	d1,d1
	addx.l	d0,d0
	subq.w	#8,d7
2:	bclr.l	#20,d0
	beq	1b
	add.w	d7,d7
	swap.w	d0
	or.w	d7,d0
	swap.w	d0
	rts

1:	moveq.l	#111,d0
	bsr	randomize
rnd_long::
	move.w	(rnd_count,pc),d0
	bmi	1b
	cmp.w	#54,d0
	bne	2f
	bsr	rnd_shuffle
	moveq.l	#-1,d0
2:	addq.w	#1,d0
	move.w	d0,rnd_count
	move.l	(rnd_table,pc,d0.w*4),d0
	rts

;----------------------------------------------------------------
;$FE41	__SINH
;	双曲正弦(sinh)を計算します。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
;>c-flag:cs=エラー(オーバーフローまたはアンダーフロー)
;	{exp(X)-1/exp(X)}/2
fe_sinh::
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fpsp	sinh
	fmove.d	fp0,-(sp)
		tst.b	d7
	bmi	@f
	exit	d0,d1

@@:	exit	C,d0,d1

;----------------------------------------------------------------
;$FE42	__COSH
;	双曲余弦(cosh)を計算します。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
;>c-flag:cs=エラー(オーバーフローまたはアンダーフロー)
;	{exp(X)+1/exp(X)}/2
fe_cosh::
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fpsp	cosh
	fmove.d	fp0,-(sp)
		tst.b	d7
	bmi	@f
	exit	d0,d1

@@:	exit	C,d0,d1

;----------------------------------------------------------------
;$FE43	__TANH
;	双曲正接(tanh)を計算します。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
;>c-flag:cs=エラー(オーバーフローまたはアンダーフロー)
;	-EXP(-X)/(EXP(X)+EXP(-X))*2+1
fe_tanh::
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fpsp	tanh
	fmove.d	fp0,-(sp)
		tst.b	d7
	bmi	@f
	exit	d0,d1

@@:	exit	C,d0,d1

;----------------------------------------------------------------
;$FE44	__ATANH
;	逆双曲正接(atanh)を計算します。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
;>c-flag:cs=エラー(引数が-1以下または+1以上)
;	LOG((1+X)/(1-X))/2
fe_atanh::
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fpsp	atanh
	fmove.d	fp0,-(sp)
		tst.b	d7
	bmi	@f
	exit	d0,d1

@@:	exit	C,d0,d1

;----------------------------------------------------------------
;$FE45	__ASIN
;	逆正弦(asin)を計算します。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
;>c-flag:cs=エラー(引数が-1以上+1以下の範囲に含まれていない)
;	ATAN(X/SQRT(1-X*X))
fe_asin::
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fpsp	asin
	fmove.d	fp0,-(sp)
		tst.b	d7
	bmi	@f
	exit	d0,d1

@@:	exit	C,d0,d1

;----------------------------------------------------------------
;$FE46	__ACOS
;	逆余弦(acos)を計算します。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
;>c-flag:cs=エラー(引数が-1以上+1以下の範囲に含まれていない)
;	ATAN(X/SQRT(1-X*X))+π/2
fe_acos::
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fpsp	acos
	fmove.d	fp0,-(sp)
		tst.b	d7
	bmi	@f
	exit	d0,d1

@@:	exit	C,d0,d1

;----------------------------------------------------------------
;$FE47	__LOG10
;	常用対数(log10 X)を計算します。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
;>c-flag:cs=エラー(オーバーフローまたはアンダーフロー)
;	logn(X)/logn(10)
fe_log10::
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fpsp	log10
	fmove.d	fp0,-(sp)
		tst.b	d7
	bmi	@f
	exit	d0,d1

@@:	exit	C,d0,d1

;----------------------------------------------------------------
;$FE48	__LOG2
;	ビット対数(log2)を計算します。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
;>c-flag:cs=エラー(オーバーフローまたはアンダーフロー)
;	logn(X)/logn(2)
fe_log2::
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fpsp	log2
	fmove.d	fp0,-(sp)
		tst.b	d7
	bmi	@f
	exit	d0,d1

@@:	exit	C,d0,d1

;----------------------------------------------------------------
;$FE49	__DFREXP
;	8バイト浮動小数点数の仮数部と指数部を分けます。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:仮数部を示す8バイト浮動小数点数
;>d2.l:指数部を示す符号つき整数
;	返り値のd0-d1の形式は引数の指数部を1に、仮数部をそのままにして返します。
fe_dfrexp::
	move.l	d0,d2
	lsl.l	#1,d2			;符号を無視
	or.l	d1,d2
	beq	1f			;0
	swap.w	d0
	move.w	d0,d2			;seeeeeeeeeeemmmm
	lsl.w	#1,d2			;eeeeeeeeeeemmmm0
	lsr.w	#5,d2			;00000eeeeeeeeeee
	sub.w	#$03FF,d2
	ext.l	d2			;指数部(符号つき)
	and.w	#$800F,d0		;指数部を1にする
	or.w	#$3FF0,d0		;
	swap.w	d0
	exit

1:	moveq.l	#0,d0
	moveq.l	#0,d1
	moveq.l	#0,d2
	exit

;----------------------------------------------------------------
;$FE4A	__DLDEXP
;	指数部と仮数部を結合して8バイト浮動小数点数を返します。
;<d0-d1:仮数部データ(8バイト浮動小数点数)
;<d2.l:指数部データ(4バイト符号つき整数)
;>d0-d1:合成された8バイト浮動小数点数
;>c-flag:cs=エラー
;	引数のd0-d1の指数部にd2の値+$3FFを加算します。
fe_dldexp::
	move.l	d0,d7			;0のときは指数部を変更しない
	lsl.l	#1,d7
	or.l	d1,d7
	beq	1f			;0のとき
	swap.w	d0
	move.w	d0,d7			;seeeeeeeeeeemmmm
	lsl.w	#1,d7			;eeeeeeeeeeemmmm0
	lsr.w	#5,d7			;00000eeeeeeeeeee
	ext.l	d7
	add.l	d2,d7			;指数部を加算
	beq	2f
	cmp.l	#$000007FF,d7
	bcc	2f
	lsl.w	#4,d7			;指数部を合成
	and.w	#$800F,d0
	or.w	d7,d0
	swap.w	d0
	exit	_

1:	moveq.l	#0,d0			;0のとき
					;d1.lは既に0
	exit	_

2:	swap.w	d0			;d0-d1を元に戻す
	exit	C

;----------------------------------------------------------------
;$FE4B	__DADDONE
;	8バイト浮動小数点数に1を加えます。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
fe_daddone::
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
	fadd.s	#0f1,fp0
	fmove.d	fp0,-(sp)
	exit	d0,d1

;----------------------------------------------------------------
;$FE4C	__DSUBONE
;	8バイト浮動小数点数から1を引きます。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
fe_dsubone::
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
	fsub.s	#0f1,fp0
	fmove.d	fp0,-(sp)
	exit	d0,d1

;----------------------------------------------------------------
;$FE4D	__DDIVTWO
;	8バイト浮動小数点数を2で割ります。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:演算結果
;>c-flag:cs=エラー(アンダーフロー)
fe_ddivtwo::
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
	fdiv.s	#0f2,fp0
	fmove.d	fp0,-(sp)
	exit	d0,d1

;----------------------------------------------------------------
;$FE4E	__DIEECNV
;	8バイト浮動小数点数をIEEEフォーマットに変換します。
;<d0-d1:8バイト浮動小数点数
;>d0-d1:IEEEフォーマット8バイト浮動小数点数
;	FLOAT2.X、FLOAT3.Xでは変換しません。
fe_dieecnv::
	exit

;----------------------------------------------------------------
;$FE4F	__IEEDCNV
;	IEEEフォーマットを8バイト浮動小数点数に変換します。
;<d0-d1:IEEEフォーマット8バイト浮動小数点数
;>d0-d1:8バイト浮動小数点数
;	FLOAT2.X、FLOAT3.Xでは変換しません。
fe_ieedcnv::
	exit

;----------------------------------------------------------------
;$FE50	__FVAL
;	文字列を4バイト浮動小数点数に変換します。
;<a0.l:文字列を指すポインタ
;>d0.l:変換された4バイト浮動小数点数
;>c-flag:cs=エラー
;>n-flag:(cs)mi=数値の記述法がおかしい
;>v-flag:(cs)vs=オーバーフロー
;	文字列が10進数以外の場合、その先頭には、2進数では'&B'、8進数では'&O'、
;	16進数では'&H'が必要です。
;	10進数の場合、返り値として次のものが追加されます。
;		d2.w	整数フラグ
;		d3.l	整数値
;	文字列が整数(小数部及び指数部がない)で、かつ4バイト符号つき整数で表現可能な場合、
;	整数フラグは$FFFFで、整数値にその値がはいります。
;	それ以外の場合は整数フラグは0となります。
fe_fval::
1:	move.b	(a0)+,d0
	cmp.b	#' ',d0
	beq	1b
	cmp.b	#9,d0
	beq	1b
	cmp.b	#'&',d0
	beq	2f
	subq.w	#1,a0
	bsr	stod
	exit	D7

2:	moveq.l	#0,d2			;整数フラグ
	moveq.l	#0,d3
	move.b	(a0)+,d0
	cmp.b	#'H',d0
	beq	3f
	cmp.b	#'B',d0
	beq	4f
	cmp.b	#'O',d0
	beq	5f
	subq.w	#1,a0			;純正品は戻していない
	exit	C,N

3:	bsr	stoh
	bne	6f
	bra	fe_ltof

4:	bsr	stob
	bne	6f
	bra	fe_ltof

5:	bsr	stoo
	bne	6f
	bra	fe_ltof

6:	exit	D7

;----------------------------------------------------------------
;$FE51	__FUSING
;	4バイト浮動小数点数を文字列に変換します。
;<d0.l:4バイト浮動小数点数
;<d2.l:整数部分の桁数
;<d3.l:小数部分の桁数
;<d4.l:アトリビュート
;<a0.l:変換された文字列の格納用バッファを指すポインタ
;>(a0):変換された文字列
;	アトリビュートはビット0~6をセットすることにより以下のような数値表現ができます。
;	ビット0:左側を'*'でパッティングします。
;	ビット1:'\'を先頭に付加します。
;	ビット2:整数部分を3桁ごとに','で区切ります。
;	ビット3:指数形式で表現します。
;	ビット4:正数の場合'+'を先頭に付加します。
;	ビット5:正数の場合'+'を、負数の場合'-'を最後尾に付加します。
;	ビット6:正数の場合' 'を、負数の場合'-'を最後尾に付加します。
fe_fusing::
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	fmove.s	(sp)+,fp0
	bsr	using
	exit	d1

;----------------------------------------------------------------
;$FE52	__STOF
;	文字列を4バイト浮動小数点数に変換します。
;<a0.l:文字列を指すポインタ
;>d0.l:変換された4バイト浮動小数点数
;>d2.w:整数フラグ
;>d3.l:整数値
;>c-flag:cs=エラー
;>n-flag:(cs)mi=数値の記述法がおかしい
;>v-flag:(cs)vs=オーバーフロー
;	文字列が整数(小数部及び指数部がない)で、かつ4バイト符号つき整数で表現可能な場合、
;	整数フラグは$FFFFで、整数値にその値がはいります。
;	それ以外の場合は整数フラグは0となります。
fe_stof::
	move.l	d1,-(sp)
	bsr	stod
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
	fmove.l	#$00000000,fpsr
	fmove.s	fp0,d0
	fmove.l	fpsr,d1
	and.b	#i|v|u|0|0|0|0|0,d1	;ivu00000
	beq	@f
	add.b	d1,d1			;vu000000
	rol.b	#2,d1			;000000vu
	or.b	#0|0|0|0|C,d1		;000000vc
	or.b	d1,d7
@@:	exit	D7,d1

;----------------------------------------------------------------
;$FE53	__FTOS
;	4バイト浮動小数点数を文字列に変換します。
;<d0.l:4バイト浮動小数点数
;<a0.l:変換された文字列の格納用バッファを指すポインタ
;<(a0):変換された文字列
fe_ftos::
	move.l	d2,-(sp)
	move.l	d1,-(sp)
	cmp.l	#$7F800000,d0
	bge	1f
	cmp.l	#$FF800000,d0
	bhs	1f
	move.l	d0,-(sp)
	fmove.s	(sp)+,fp0
	bsr	dtos
	exit	d1,d2

1:	bne	2f
	tst.l	d1
	bne	2f
	tst.l	d0
	bpl	@f
	move.b	#'-',(a0)+
@@:	move.l	#'#INF',(a0)+
	bra	3f

2:	move.l	#'#NAN',(a0)+
3:	clr.b	(a0)
	exit	d1,d2

;----------------------------------------------------------------
;$FE54	__FECVT
;	4バイト浮動小数点数を全体の桁数を指定して文字列に変換します。
;<d0.l:4バイト浮動小数点数
;<d2.b:全体の桁数
;<a0.l:変換された文字列の格納用バッファを指すポインタ
;>d0.l:小数点の位置
;>d1.l:符号(0=正,1=負)
;>(a0):変換された文字列
fe_fecvt::
	move.l	d2,-(sp)
	move.l	d1,-(sp)
	and.l	#$000000FF,d2
	cmp.l	#$7F800000,d0
	bge	9f
	cmp.l	#$FF800000,d0
	bhs	9f
	move.l	d0,-(sp)
	fmove.s	(sp)+,fp0
	move.l	a0,-(sp)		;a0を破壊しない
	bsr	ecvt
	movea.l	(sp)+,a0
	exit	d1,d2

9:	bne	1f
	tst.l	d1
	bne	1f
	moveq.l	#0,d1
	tst.l	d0
	bpl	@f
	moveq.l	#1,d1
	subq.l	#1,d2			;純正は桁数が足りないと$00をいれようとする
	bcs	2f
	move.b	#'-',(a0)+
@@:	subq.l	#1,d2
	bcs	2f
	move.b	#'#',(a0)+
	subq.l	#1,d2
	bcs	2f
	move.b	#'I',(a0)+
	subq.l	#1,d2
	bcs	2f
	move.b	#'N',(a0)+
	subq.l	#1,d2
	bcs	2f
	move.b	#'F',(a0)+
	bra	2f

1:	moveq.l	#0,d1
	subq.l	#1,d2
	bcs	2f
	move.b	#'#',(a0)+
	subq.l	#1,d2
	bcs	2f
	move.b	#'N',(a0)+
	subq.l	#1,d2
	bcs	2f
	move.b	#'A',(a0)+
	subq.l	#1,d2
	bcs	2f
	move.b	#'N',(a0)+
2:	clr.b	(a0)
	move.l	#4,d0			;常に4
	exit	d1,d2

;----------------------------------------------------------------
;$FE55	__FFCVT
;	4バイト浮動小数点数を小数点以下の桁数を指定して、文字列に変換します。
;<d0.l:4バイト浮動小数点数
;<d2.b:小数点以下の桁数
;<a0.l:変換された文字列の格納用バッファを指すポインタ
;>d0.l:小数点の位置
;>d1.l:符号(0=正,1=負)
;>(a0):変換された文字列
fe_ffcvt::
	move.l	d2,-(sp)
	move.l	d1,-(sp)
	and.l	#$000000FF,d2
	cmp.l	#$7F800000,d0
	bge	9f
	cmp.l	#$FF800000,d0
	bhs	9f
	move.l	d0,-(sp)
	fmove.s	(sp)+,fp0
	move.l	a0,-(sp)		;a0を破壊しない
	bsr	fcvt
	movea.l	(sp)+,a0
	exit	d1,d2

9:	bne	1f
	tst.l	d1
	bne	1f
	moveq.l	#0,d1
	tst.l	d0
	bpl	@f
	moveq.l	#1,d1
	move.b	#'-',(a0)+
@@:	move.l	#'#INF',(a0)+		;奇数アドレスの可能性がある
					;純正は桁数が足りないと$00に指数を付けて結局はみ出す
	bra	2f

1:	moveq.l	#0,d1
	move.l	#'#NAN',(a0)+		;奇数アドレスの可能性がある
2:	clr.b	(a0)
	move.l	#4,d0			;常に4
	exit	d1,d2

;----------------------------------------------------------------
;$FE56	__FGCVT
;	4バイト浮動小数点数を全体の桁数を指定した浮動小数点表現または指数表現の文字列に
;	変換します。
;<d0.l:4バイト浮動小数点数
;<d2.b:全体の桁数
;<a0.l:変換された文字列の格納用バッファを指すポインタ
;>(a0):変換された文字列
;	負の値の場合は文字列の先頭にマイナス記号('-')が付加されます。
;	d2の桁数で表現できない場合に、指数表現の文字列に変換します。
fe_fgcvt::
	move.l	d2,-(sp)
	move.l	d1,-(sp)
	and.l	#$000000FF,d2
	cmp.l	#$7F800000,d0
	bge	9f
	cmp.l	#$FF800000,d0
	bhs	9f
	move.l	d0,-(sp)
	fmove.s	(sp)+,fp0
	bsr	gcvt
	exit	d1,d2

9:	bne	1f
	tst.l	d1
	bne	1f
	moveq.l	#0,d1
	tst.l	d0
	bpl	@f
	moveq.l	#1,d1
	move.b	#'-',(a0)+
@@:	move.l	#'#INF',(a0)+		;奇数アドレスの可能性がある
					;純正は桁数が足りないと$00に指数を付けて結局はみ出す
	bra	2f

1:	moveq.l	#0,d1
	move.l	#'#NAN',(a0)+		;奇数アドレスの可能性がある
2:	clr.b	(a0)
	move.l	#4,d0			;常に4
	exit	d1,d2

;----------------------------------------------------------------
;$FE58	__FTST
;	4バイト浮動小数点数と0の比較をします。
;<d0.l:4バイト浮動小数点数
;>z-flag:eq=0
;>n-flag:mi=負
fe_ftst::
	cmp.l	#$80000000,d0
	beq	@f
	tst.l	d0
@@:	exit	ccr

;----------------------------------------------------------------
;$FE59	__FCMP
;	4バイト浮動小数点数どうしの比較をします。
;<d0.l:被比較数
;<d1.l:比較数
;	被比較数から比較数を減算した結果にしたがってセットされます。
;>n-flag:mi=負
;>z-flag:eq=0
;>c-flag:cs=ボローが発生した
;	被比較数が比較数より大きいとき	cc,ne,pl
;	被比較数が比較数と等しいとき	cc,eq,pl
;	被比較数が比較数より小さいとき	cs,ne,mi
fe_fcmp::
	tst.l	d0
	bmi	1f
	tst.l	d1
	bmi	2f
	cmp.l	d1,d0
	exit	ccr

1:	tst.l	d1
	bpl	3f
	cmp.l	d0,d1
	exit	ccr

2:	exit	_

3:	exit	C,N

;----------------------------------------------------------------
;$FE5A	__FNEG
;	4バイト浮動小数点数の符号を反転します。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
fe_fneg::
	tst.l	d0
	beq	@f
	bchg.l	#31,d0
@@:	exit

;----------------------------------------------------------------
;$FE5B	__FADD
;	4バイト浮動小数点数どうしの加算をします。
;<d0.l:被加算数
;<d1.l:加算数
;>d0.l:演算結果
;>c-flag:cs=エラー
;>v-flag:(cs)vs=オーバーフロー,(cs)vc=アンダーフロー
fe_fadd::
	fmove.l	#$00000000,fpsr
	fmove.s	d0,fp0
	fadd.s	d1,fp0
	fmove.s	fp0,d0
	fmove.l	fpsr,d7
	and.b	#i|v|u|0|0|0|0|0,d7	;ivu00000
	bne	@f
	exit	_

@@:	add.b	d7,d7			;vu000000
	rol.b	#2,d7			;000000vu
	or.b	#0|0|0|0|C,d7		;000000vc
	exit	D7

;----------------------------------------------------------------
;$FE5C	__FSUB
;	4バイト浮動小数点数どうしの減算をします。
;<d0.l:被減算数
;<d1.l:減算数
;>d0.l:演算結果
;>c-flag:cs=エラー
;>v-flag:(cs)vs=オーバーフロー,(cs)vc=アンダーフロー
fe_fsub::
	fmove.l	#$00000000,fpsr
	fmove.s	d0,fp0
	fsub.s	d1,fp0
	fmove.s	fp0,d0
	fmove.l	fpsr,d7
	and.b	#i|v|u|0|0|0|0|0,d7	;ivu00000
	bne	@f
	exit	_

@@:	add.b	d7,d7			;vu000000
	rol.b	#2,d7			;000000vu
	or.b	#0|0|0|0|C,d7		;000000vc
	exit	D7

;----------------------------------------------------------------
;$FE5D	__FMUL
;	4バイト浮動小数点数どうしの乗算をします。
;<d0.l:被乗数
;<d1.l:乗数
;>d0.l:演算結果
;>c-flag:cs=エラー
;>v-flag:(cs)vs=オーバーフロー,(cs)vc=アンダーフロー
fe_fmul::
	fmove.l	#$00000000,fpsr
	fmove.s	d0,fp0
	fsglmul.s	d1,fp0
	fmove.s	fp0,d0
	fmove.l	fpsr,d7
	and.b	#i|v|u|0|0|0|0|0,d7	;ivu00000
	bne	@f
	exit	_

@@:	add.b	d7,d7			;vu000000
	rol.b	#2,d7			;000000vu
	or.b	#0|0|0|0|C,d7		;000000vc
	exit	D7

;----------------------------------------------------------------
;$FE5E	__FDIV
;	4バイト浮動小数点数どうしの除算をします。
;<d0.l:被除数
;<d1.l:除数
;>d0.l:演算結果
;>c-flag:cs=エラー
;>z-flag:(cs)eq=0で割った
;>v-flag:(cs,ne)vs=オーバーフロー,(cs,ne)vc=アンダーフロー
fe_fdiv::
	fmove.l	#$00000000,fpsr
	fmove.s	d0,fp0
	fsgldiv.s	d1,fp0
	fmove.s	fp0,d0
	fmove.l	fpsr,d7
	and.b	#i|v|u|z|0|0|0|0,d7	;ivuz0000
	bne	@f
	exit	_

@@:	add.b	d7,d7			;vuz00000
	rol.b	#2,d7			;z00000vu
	bpl	@f
	addq.b	#4,d7			;z0000zvu
@@:	or.b	#0|0|0|0|C,d7		;z0000zvc
	exit	D7

;----------------------------------------------------------------
;$FE5F	__FMOD
;	4バイト浮動小数点数どうしの剰余を求めます。
;<d0.l:被除数
;<d1.l:除数
;>d0.l:演算結果
;>c-flag:cs=エラー
;>z-flag:(cs)eq=0で割った
;>v-flag:(cs,ne)vs=有効数字の範囲外,(cs,ne)vc=アンダーフロー
fe_fmod::
	tst.l	d1
	beq	1f
	fmove.l	#$00000000,fpsr
	fmove.s	d0,fp0
	fmod.s	d1,fp0			;エミュレーション
	fmove.s	fp0,d0
	fmove.l	fpsr,d7
	and.b	#i|v|u|z|0|0|0|0,d7	;ivuz0000
	bne	@f
	exit	_

@@:	add.b	d7,d7			;vuz00000
	rol.b	#2,d7			;z00000vu
	bpl	@f
	addq.b	#4,d7			;z0000zvu
@@:	or.b	#0|0|0|0|C,d7		;z0000zvc
	exit	D7

1:	move.l	#$7FFFFFFF,d0
	exit	C,Z

;----------------------------------------------------------------
;$FE60	__FABS
;	4バイト浮動小数点数の絶対値を求めます。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
fe_fabs::
	bclr.l	#31,d0
	exit

;----------------------------------------------------------------
;$FE61	__FCEIL
;	4バイト浮動小数点数と等しいか、それ以上の最小の整数を返します。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
fe_fceil::
	fmove.l	fpcr,d7
	fmove.l	#FPRM_RP,fpcr
	fint.s	d0,fp0
	fmove.s	fp0,d0
	fmove.l	d7,fpcr
	exit

;----------------------------------------------------------------
;$FE62	__FFIX
;	4バイト浮動小数点数の整数部を求めます。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
fe_ffix::
	fintrz.s	d0,fp0
	fmove.s	fp0,d0
	exit

;----------------------------------------------------------------
;$FE63	__FFLOOR
;	4バイト浮動小数点数と等しいかまたはそれより小さい最大の整数を返します。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
fe_ffloor::
	fmove.l	fpcr,d7
	fmove.l	#FPRM_RM,fpcr
	fint.s	d0,fp0
	fmove.s	fp0,d0
	fmove.l	d7,fpcr
	exit

;----------------------------------------------------------------
;$FE64	__FFRAC
;	4バイト浮動小数点数の小数部を求めます。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
fe_ffrac::
	fmove.s	d0,fp0
	fintrz.x	fp0,fp1
	fsub.x	fp1,fp0
	fmove.s	fp0,d0
	exit

  .comment ********
	move.l	d2,-(sp)
	move.l	d0,d2
	swap.w	d2
	asr.w	#7,d2
	move.w	d2,-(sp)
	and.w	#$00FF,d2
	sub.w	#$007E,d2
	bls	3f
	cmp.w	#$002F,d2
	bhi	4f			;指数部が大きすぎる
	lsl.l	d2,d0
	and.l	#$00FFFFFF,d0
	beq	4f			;小数部が0
	moveq.l	#$17,d7
	btst.l	d7,d0
	bne	2f
1:	addq.w	#1,d2			;小数部を正規化する
	add.l	d0,d0
	btst.l	d7,d0
	beq	1b
2:	sub.w	(sp)+,d2
	neg.w	d2
	lsl.w	#7,d2
	swap.w	d0
	and.w	#$007F,d0
	add.w	d2,d0
	swap.w	d0
	exit	d2

3:	addq.l	#2,sp
	exit	d2

4:	move.w	(sp)+,d0
	swap.w	d0
	and.l	#$80000000,d0
	exit	d2
  ******** ********

;----------------------------------------------------------------
;$FE65	__FSGN
;	4バイト浮動小数点数が正か負か0かを調べます。
;<d0.l:4バイト浮動小数点数
;>d0.l:結果(4バイト浮動小数点数)
;	正なら+1、負なら-1、0なら0を返します。
fe_fsgn::
	add.l	d0,d0
	beq	@f
	move.l	#$3F800000<<1,d0
	roxr.l	#1,d0
@@:	exit

;----------------------------------------------------------------
;$FE66	__FSIN
;	角度(ラジアン単位)を与えて正弦(sin)を計算します。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
fe_fsin::
	fmove.s	d0,fp0
	fpsp	sin
	fmove.s	fp0,d0
		tst.b	d7
	bmi	@f
	exit	_

@@:	exit	C

;----------------------------------------------------------------
;$FE67	__FCOS
;	角度(ラジアン単位)を与えて余弦(cos)を計算します。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
fe_fcos::
	fmove.s	d0,fp0
	fpsp	cos
	fmove.s	fp0,d0
		tst.b	d7
	bmi	@f
	exit	_

@@:	exit	C

;----------------------------------------------------------------
;$FE68	__FTAN
;	角度(ラジアン単位)を与えて正接(tan)を計算します。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
;>c-flag:cs=エラー(引数が、((2n+1)/2)π(n:整数))
fe_ftan::
	fmove.s	d0,fp0
	fpsp	tan
	fmove.s	fp0,d0
		tst.b	d7
	bmi	@f
	exit	_

@@:	exit	C

;----------------------------------------------------------------
;$FE69	__FATAN
;	逆正接(atan)を計算します。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果(ラジアン単位)
fe_fatan::
	fmove.s	d0,fp0
	fpsp	atan
	fmove.s	fp0,d0
		tst.b	d7
	bmi	@f
	exit	_

@@:	exit	C

;----------------------------------------------------------------
;$FE6A	__FLOG
;	自然対数(log)を計算します。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
;>c-flag:cs=エラー(引数が0または負)
;>z-flag:(cs)eq=引数が0(log 0)
fe_flog::
	fmove.s	d0,fp0
	fpsp	logn
	fmove.s	fp0,d0
		tst.b	d7
	bmi	@f
	exit	_

@@:	exit	C

;----------------------------------------------------------------
;$FE6B	__FEXP
;	指数関数(e^x)を計算します。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
;>c-flag:cs=エラー(オーバーフロー)
fe_fexp::
	fmove.s	d0,fp0
	fpsp	etox
	fmove.s	fp0,d0
		tst.b	d7
	bmi	@f
	exit	_

@@:	exit	C

;----------------------------------------------------------------
;$FE6C	__FSQR
;	平方根を計算します。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
;>c-flag:cs=エラー(引数が負)
fe_fsqr::
	tst.l	d0
	bmi	9f
	fmove.l	#$00000000,fpsr
	fsqrt.s	d0,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fmove.s	fp0,d0
	fmove.l	fpsr,d7
	and.b	#i|v|u|0|0|0|0|0,d7	;ivu00000
	bne	@f
	exit

@@:	add.b	d7,d7			;vu000000
	rol.b	#2,d7			;000000vu
	or.b	#0|0|0|0|C,d7		;000000vc
	exit	D7

9:	exit	C

;----------------------------------------------------------------
;$FE6D	__FPI
;	円周率を4バイト浮動小数点数の範囲内で返します。
;>d0.l:演算結果
fe_fpi::
	move.l	#$40490FDB,d0
	exit

;----------------------------------------------------------------
;$FE6E	__FNPI
;	円周率と4バイト浮動小数点数の積(xπ)を計算します。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
;>c-flag:cs=エラー(オーバーフロー)
fe_fnpi::
	fmove.l	#$00000000,fpsr
	fmove.x	pi(pc),fp0		
	fsglmul.s	d0,fp0
	fmove.s	fp0,d0
	fmove.l	fpsr,d7
	and.b	#i|v|u|0|0|0|0|0,d7	;ivu00000
	bne	@f
	exit	_

@@:	add.b	d7,d7			;vu000000
	rol.b	#2,d7			;000000vu
	or.b	#0|0|0|0|C,d7		;000000vc
	exit	D7

;----------------------------------------------------------------
;$FE6F	__FPOWER
;	べき乗(X^y)を計算します。
;<d0.l:被べき乗数
;<d1.l:指数
;>d0.l:演算結果
;>c-flag:cs=エラー
;>v-flag:(cs)vs=オーバーフロー,(cs)vc=アンダーフロー
fe_fpower::
	bsr	~001F80
	exit	ccr

~001F80:
	move.l	d0,-(sp)
	add.l	d0,d0
	cmpi.l	#$FFFFFFFE,d0
	beq	~001FDE
	move.l	d1,d0
	add.l	d0,d0
	beq	~00202C
	cmpi.l	#$FF000000,d0
	bcc	~001FE6
	move.l	(sp),d0
	add.l	d0,d0
	beq	~00203E
	bcs	~002048
	fmove.l	#$00000000,fpsr
	flogn.s	(sp),fp0		;エミュレーション
	fmul.s	d1,fp0
	fetox.x	fp0			;エミュレーション
	fmove.s	fp0,(sp)
	fmove.l	fpsr,d0
	and.w	#FPAE_IOP|FPAE_OVFL|FPAE_DZ,d0
	beq	~001FD6
	add.b	d0,d0
	add.b	d0,d0
	bcc	~001FD2
	addq.b	#1,d0
~001FD2:
	add.b	d0,d0
	addq.b	#1,d0
~001FD6:
	move.w	d0,ccr
	movem.l	(sp)+,d0
	rts

~001FDE:
	move.l	(sp)+,d0
	move.w	#$0000,ccr
	rts

~001FE6:
	beq	~001FF2
	move.l	d1,d0
	addq.l	#4,sp
	move.w	#$0000,ccr
	rts

~001FF2:
	move.l	(sp),d0
	add.l	d0,d0
	beq	~0020B6
	cmp.l	#$FF000000,d0
	beq	~00201A
	tst.l	d1
	bmi	~00203A
~002006:
	move.l	(sp)+,d0
	and.l	#$80000000,d0
	or.l	#$7F800000,d0
	move.w	#$0000,ccr
	rts

~00201A:
	tst.l	d1
	bpl	~002006
	move.l	(sp)+,d0
	or.l	#$7FFFFFFF,d0
	move.w	#$0000,ccr
	rts

~00202C:
	move.l	#$3F800000,d0
	move.w	#$0000,ccr
	addq.l	#4,sp
	rts

~00203A:
	tst.l	(sp)
	bmi	~0020B6
~00203E:
	moveq.l	#$00,d0
	move.w	#$0000,ccr
	addq.l	#4,sp
	rts

~002048:
	fmove.s	(sp),fp1
	move.l	d1,d0
;	bsr	fe_ffrac		;__FFRAC
	fmove.s	d0,fp0
	fintrz.x	fp0,fp1
	fsub.x	fp1,fp0
	fmove.s	fp0,d0
;
	add.l	d0,d0
	bne	~0020B6
	fmove.l	#$00000000,fpsr
	fmove.s	d1,fp0
	fmove.l	fp0,d0
	tst.l	d0
	beq	~00202C
	bpl	~00207A
	fmove.x	one(pc),fp0
	fdiv.x	fp1,fp0
	fmove.x	fp0,fp1
	neg.l	d0
~00207A:
	fmove.x	one(pc),fp0
~00207E:
	lsr.l	#1,d0
	bcc	~00208A
	fmul.x	fp1,fp0
	tst.l	d0
	beq	~002090
~00208A:
	fmul.x	fp1,fp1
	bra	~00207E

~002090:
	fmove.s	fp0,(sp)
	fmove.l	fpsr,d0
	and.w	#FPAE_IOP|FPAE_OVFL|FPAE_UNFL|FPAE_DZ,d0
	beq	~0020AE
	add.b	d0,d0
	add.b	d0,d0
	bcc	~0020A6
	addq.b	#1,d0
~0020A6:
	add.b	d0,d0
	bpl	~0020AC
	addq.b	#4,d0
~0020AC:
	addq.b	#1,d0
~0020AE:
	move.w	d0,ccr
	movem.l	(sp)+,d0
	rts

~0020B6:
	move.l	#$7FFFFFFF,d0
	move.w	#SRU_C,ccr
	addq.l	#4,sp
	rts

;----------------------------------------------------------------
;$FE70	__FRND
;	4バイト浮動小数点数の乱数を返します。
;>d0.l:4バイト浮動小数点数の乱数(0以上1未満)
fe_frnd::
	bsr	rnd
	move.l	d1,-(sp)
		move.l	d0,-(sp)
	fmove.d	(sp)+,fp0
	fmove.s	fp0,d0
	exit

;----------------------------------------------------------------
;$FE71	__FSINH
;	双曲正弦(sinh)を計算します。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
;>c-flag:cs=エラー(オーバーフローまたはアンダーフロー)
fe_fsinh::
	fmove.s	d0,fp0
	fpsp	sinh
	fmove.s	fp0,d0
		tst.b	d7
	bmi	@f
	exit	_

@@:	exit	C

;----------------------------------------------------------------
;$FE72	__FCOSH
;	双曲余弦(cosh)を計算します。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
;>c-flag:cs=エラー(オーバーフローまたはアンダーフロー)
fe_fcosh::
	fmove.s	d0,fp0
	fpsp	cosh
	fmove.s	fp0,d0
		tst.b	d7
	bmi	@f
	exit	_

@@:	exit	C

;----------------------------------------------------------------
;$FE73	__FTANH
;	双曲正接(tanh)を計算します。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
;>c-flag:cs=エラー(オーバーフローまたはアンダーフロー)
fe_ftanh::
	fmove.s	d0,fp0
	fpsp	tanh
	fmove.s	fp0,d0
		tst.b	d7
	bmi	@f
	exit	_

@@:	exit	C

;----------------------------------------------------------------
;$FE74	__FATANH
;	逆双曲正接(atanh)を計算します。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
;>c-flag:cs=エラー(オーバーフローまたはアンダーフロー)
fe_fatanh::
	fmove.s	d0,fp0
	fpsp	atanh
	fmove.s	fp0,d0
		tst.b	d7
	bmi	@f
	exit	_

@@:	exit	C

;----------------------------------------------------------------
;$FE75	__FASIN
;	逆正弦(asin)を計算します。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
;>c-flag:cs=エラー(引数が-1以上+1以下の範囲に含まれていない)
fe_fasin::
	fmove.s	d0,fp0
	fpsp	asin
	fmove.s	fp0,d0
		tst.b	d7
	bmi	@f
	exit	_

@@:	exit	C

;----------------------------------------------------------------
;$FE76	__FACOS
;	逆余弦(acos)を計算します。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
;>c-flag:cs=エラー(引数が-1以上+1以下の範囲に含まれていない)
fe_facos::
	fmove.s	d0,fp0
	fpsp	acos
	fmove.s	fp0,d0
		tst.b	d7
	bmi	@f
	exit	_

@@:	exit	C

;----------------------------------------------------------------
;$FE77	__FLOG10
;	常用対数(log10 X)を計算します。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
;>c-flag:cs=エラー(オーバーフローまたはアンダーフロー)
fe_flog10::
	fmove.s	d0,fp0
	fpsp	log10
	fmove.s	fp0,d0
		tst.b	d7
	bmi	@f
	exit	_

@@:	exit	C

;----------------------------------------------------------------
;$FE78	__FLOG2
;	ビット対数(log2)を計算します。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
;>c-flag:cs=エラー(オーバーフローまたはアンダーフロー)
fe_flog2::
	fmove.s	d0,fp0
	fpsp	log2
	fmove.s	fp0,d0
		tst.b	d7
	bmi	@f
	exit	_

@@:	exit	C

;----------------------------------------------------------------
;$FE79	__FFREXP
;	4バイト浮動小数点数の仮数部と指数部を分けます。
;<d0.l:4バイト浮動小数点数
;>d0.l:仮数部を示す4バイト浮動小数点数
;>d1.l:指数部を示す4バイト符号つき整数
;	返り値のd0は、引数の指数部を1に、仮数部をそのままにして返します。
fe_ffrexp::
	move.l	d0,d1			;seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm
	lsl.l	#1,d1			;eeeeeeeemmmmmmmmmmmmmmmmmmmmmmm0
	beq	1f			;0のとき
	swap.w	d1			;eeeeeeeemmmmmmmm
	lsr.w	#8,d1			;00000000eeeeeeee
	sub.w	#$007F,d1
	ext.l	d1			;指数部(符号つき)
	and.l	#$807FFFFF,d0		;符号と仮数部を残して指数部を1にする
	or.l	#$3F800000,d0		;
	exit

1:	moveq.l	#0,d0			;符号を消す
					;d1.lは既に0
	exit

;----------------------------------------------------------------
;$FE7A	__FLDEXP
;	指数部と仮数部を結合して4バイト浮動小数点数を返します。
;<d0.l:仮数部データ(4バイト浮動小数点数)
;<d1.l:指数部データ(4バイト符号つき整数)
;>d0.l:合成された4バイト浮動小数点数
;>c-flag:cs=エラー
;	引数のd0の指数部にd1の値+$7Fを加算します。
fe_fldexp::
	move.l	d0,d7			;seeeeeeeemmmmmmm_mmmmmmmmmmmmmmmm
	lsl.l	#1,d7			;eeeeeeeemmmmmmmm_mmmmmmmmmmmmmmm0
	beq	1f			;0のとき
	swap.w	d7			;eeeeeeeemmmmmmmm
	lsr.w	#8,d7			;00000000eeeeeeee
	ext.l	d7
	add.l	d1,d7			;指数部を加算
	beq	2f
	cmp.l	#$00000FF,d7
	bcc	2f
	lsl.w	#7,d7			;0eeeeeeee0000000
	swap.w	d7			;0eeeeeeee0000000_0000000000000000
	and.l	#$807FFFFF,d0
	or.l	d7,d0
	exit	_

1:	moveq.l	#0,d0			;0のとき
	exit	_

2:	exit	C			;d0は変化しない

;----------------------------------------------------------------
;$FE7B	__FADDONE
;	4バイト浮動小数点数に1を加えます。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
fe_faddone::
	fmove.s	d0,fp0
	fadd.s	#0f1,fp0
	fmove.s	fp0,d0
	exit

;----------------------------------------------------------------
;$FE7C	__FSUBONE
;	4バイト浮動小数点数から1を引きます。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
fe_fsubone::
	fmove.s	d0,fp0
	fsub.s	#0f1,fp0
	fmove.s	fp0,d0
	exit

;----------------------------------------------------------------
;$FE7D	__FDIVTWO
;	4バイト浮動小数点数を2で割ります。
;<d0.l:4バイト浮動小数点数
;>d0.l:演算結果
;>c-flag:cs=エラー(アンダーフロー)
fe_fdivtwo::
	tst.l	d0
	beq	1f
	bmi	3f
	cmp.l	#$7F800000,d0
	bcc	1f
	sub.l	#$00800000,d0
	bcs	2f
	cmp.l	#$00800000,d0
	bcs	2f
1:	exit	_

2:	moveq.l	#0,d0
	exit	C,Z

3:	cmp.l	#$FF800000,d0
	bcc	4f
	sub.l	#$00800000,d0
	cmp.l	#$80800000,d0
	bcs	2b
4:	exit	_

;----------------------------------------------------------------
;$FE7E	__FIEECNV
;	4バイト浮動小数点数をIEEEフォーマットに変換します。
;<d0.l:4バイト浮動小数点数
;>d0.l:IEEEフォーマット4バイト浮動小数点数
;	FLOAT2.X、FLOAT3.Xでは変換しません。
fe_fieecnv::
	exit

;----------------------------------------------------------------
;$FE7F	__IEEFCNV
;	IEEEフォーマットを4バイト浮動小数点数に変換します。
;<d0.l:IEEEフォーマット4バイト浮動小数点数
;>d0.l:4バイト浮動小数点数
;	FLOAT2.X、FLOAT3.Xでは変換しません。
fe_ieefcnv::
	exit

;----------------------------------------------------------------
;$FEE0	__CLMUL
;	4バイト符号つき整数どうしの乗算をします。
;<(sp).l:被乗数の4バイト符号つき整数
;<(4,sp).l:乗数の4バイト符号つき整数
;>(sp).l:演算結果の4バイト符号つき整数
;>c-flag:cs=エラー(演算結果が4バイト符号つき整数の範囲を超えた)
fe_clmul::
	param	a6
	move.l	(a6)+,d7
	muls.l	(a6),d7
	svs.b	-(sp)
		move.l	d7,-(a6)
	move.b	(sp)+,d7
		neg.b	d7
	exit	D7

;----------------------------------------------------------------
;$FEE1	__CLDIV
;	4バイト符号つき整数どうしの除算をします。
;<(sp).l:被除数の4バイト符号つき整数
;<(4,sp).l:除数の4バイト符号つき整数
;>(sp).l:演算結果の4バイト符号つき整数
;>c-flag:cs=エラー(除数が0)
fe_cldiv::
	param	a6
	tst.l	(4,a6)
	beq	@f
	move.l	(a6)+,d7
		clr.b	4*2+1(sp)	;CCRクリア
	divs.l	(a6),d7
	exit	-7

@@:	exit	C

;----------------------------------------------------------------
;$FEE2	__CLMOD
;	4バイト符号つき整数どうしの除算の剰余を計算します。
;<(sp).l:被除数の4バイト符号つき整数
;<(4,sp).l:除数の4バイト符号つき整数
;>(sp).l:演算結果の4バイト符号つき整数
;>c-flag:cs=エラー(除数が0)
fe_clmod::
	param	a6
	tst.l	(4,a6)
	beq	@f
	move.l	(a6)+,d7
		clr.b	4*2+1(sp)	;CCRクリア
	move.l	d0,-(sp)
	divsl.l	(a6),d0:d7
	exit	-0,d0

@@:	exit	C

;----------------------------------------------------------------
;$FEE3	__CUMUL
;	4バイト符号なし整数どうしの乗算をします。
;<(sp).l:被乗数の4バイト符号つき整数
;<(4,sp).l:乗数の4バイト符号つき整数
;>(sp).l:演算結果の4バイト符号つき整数
;>c-flag:cs=エラー(演算結果が4バイト符号つき整数の範囲を超えた)
fe_cumul::
	param	a6
	move.l	(a6)+,d7
	mulu.l	(a6),d7
	svs.b	-(sp)
		move.l	d7,-(a6)
	move.b	(sp)+,d7
		neg.b	d7
	exit	D7

;----------------------------------------------------------------
;$FEE4	__CUDIV
;	4バイト符号なし整数どうしの除算をします。
;<(sp).l:被除数の4バイト符号つき整数
;<(4,sp).l:除数の4バイト符号つき整数
;>(sp).l:演算結果の4バイト符号つき整数
;>c-flag:cs=エラー(除数が0)
fe_cudiv::
	param	a6
	tst.l	(4,a6)
	beq	@f
	move.l	(a6)+,d7
		clr.b	4*2+1(sp)	;CCRクリア
	divu.l	(a6),d7
	exit	-7

@@:	exit	C

;----------------------------------------------------------------
;$FEE5	__CUMOD
;	4バイト符号なし整数どうしの除算の剰余を計算します。
;<(sp).l:被除数の4バイト符号つき整数
;<(4,sp).l:除数の4バイト符号つき整数
;>(sp).l:演算結果の4バイト符号つき整数
;>c-flag:cs=エラー(除数が0)
fe_cumod::
	param	a6
	tst.l	(4,a6)
	beq	@f
	move.l	(a6)+,d7
		clr.b	4*2+1(sp)	;CCRクリア
	move.l	d0,-(sp)
	divul.l	(a6),d0:d7
	exit	-0,d0

@@:	exit	C

;----------------------------------------------------------------
;$FEE6	__CLTOD
;	4バイト符号つき整数を8バイト浮動小数点数に変換します。
;<(sp).l:4バイト符号つき整数
;>(sp).d:変換された8バイト浮動小数点数
fe_cltod::
	param	a6
	fmove.l	(a6),fp0
	fmove.d	fp0,(a6)
	exit

;----------------------------------------------------------------
;$FEE7	__CDTOL
;	8バイト浮動小数点数を4バイト符号つき整数に変換します。
;<(sp).d:8バイト浮動小数点数
;>(sp).l:変換された4バイト符号つき整数
;>c-flag:cs=エラー(変換結果が4バイト符号つき整数の値の範囲を超えた)
;	小数部分は切り捨てられます。
;	4バイト符号つき整数の値は次の範囲です。
;		-2147483648~+2147483647
fe_cdtol::
	param	a6
	fmove.l	#$00000000,fpsr
	fintrz.d	(a6),fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fmove.l	fp0,(a6)
	fmove.l	fpsr,d7
	and.b	#i|v|0|0|0|0|0|0,d7	;iv000000
	bne	@f
	exit

@@:	add.b	d7,d7			;v0000000
	rol.b	#2,d7			;000000v0
	addq.b	#0|0|0|0|C,d7		;000000vc
	exit	D7

;----------------------------------------------------------------
;$FEE8	__CLTOF
;	4バイト符号つき整数を4バイト浮動小数点数に変換します。
;<(sp).l:4バイト符号つき整数
;>(sp).s:変換された4バイト浮動小数点数
fe_cltof::
	param	a6
	fmove.l	(a6),fp0
	fmove.s	fp0,(a6)
	exit

;----------------------------------------------------------------
;$FEE9	__CFTOL
;	4バイト浮動小数点数を4バイト符号つき整数に変換します。
;<(sp).s:4バイト浮動小数点数
;>(sp).l:変換された4バイト符号つき整数
;>c-flag:cs=エラー(変換結果が4バイト符号つき整数の値の範囲を超えた)
;	小数部分は切り捨てられます。
;	4バイト符号つき整数の値は次の範囲です。
;		-2147483648~+2147483647
fe_cftol::
	param	a6
	fmove.l	#$00000000,fpsr
	fintrz.s	(a6),fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fmove.l	fp0,(a6)
	fmove.l	fpsr,d7
	and.b	#i|v|0|0|0|0|0|0,d7	;iv000000
	bne	@f
	exit

@@:	add.b	d7,d7			;v0000000
	rol.b	#2,d7			;000000v0
	addq.b	#0|0|0|0|C,d7		;000000vc
	exit	D7

;----------------------------------------------------------------
;$FEEA	__CFTOD
;	4バイト浮動小数点数を8バイト浮動小数点数に変換します。
;<(sp).s:4バイト浮動小数点数
;>(sp).d:変換された8バイト浮動小数点数
fe_cftod::
	param	a6
	fmove.s	(a6),fp0
	fmove.d	fp0,(a6)
	exit

;----------------------------------------------------------------
;$FEEB	__CDTOF
;	8バイト浮動小数点数を4バイト浮動小数点数に変換します。
;<(sp).d:8バイト浮動小数点数
;>(sp).s:変換された4バイト浮動小数点数
;>c-flag:cs=エラー(引数が4バイト浮動小数点数で表現できない)
fe_cdtof::
	param	a6
	fmove.l	#$00000000,fpsr
	fmove.d	(a6),fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fmove.s	fp0,(a6)
	fmove.l	fpsr,d7
	and.b	#i|v|0|0|0|0|0|0,d7	;iv000000
	bne	@f
	exit

@@:	add.b	d7,d7			;v0000000
	rol.b	#2,d7			;000000v0
	addq.b	#0|0|0|0|C,d7		;000000vc
	exit	D7

;----------------------------------------------------------------
;$FEEC	__CDCMP
;	8バイト浮動小数点数どうしの比較をします。
;<(sp).d:被比較数
;<(8,sp).d:比較数
;	被比較数から比較数を減算した結果にしたがってセットされます。
;>n-flag:mi=負
;>z-flag:eq=0
;>c-flag:cs=ボローが発生した
;	被比較数が比較数より大きいとき	cc,ne,pl
;	被比較数が比較数と等しいとき	cc,eq,pl
;	被比較数が比較数より小さいとき	cs,ne,mi
fe_cdcmp::
	param	a6
	move.l	(a6),d7
	bmi	1f
	tst.l	(8,a6)
	bmi	2f
	cmp.l	(8,a6),d7
	bne	@f
	move.l	(4,a6),d7
	cmp.l	(8+4,a6),d7
@@:	exit	ccr

1:	move.l	(8,a6),d7
	bpl	3f
	cmp.l	(a6),d7
	bne	@f
	move.l	(8+4,a6),d7
	cmp.l	(4,a6),d7
@@:	exit	ccr

2:	exit	_

3:	exit	C,N

;----------------------------------------------------------------
;$FEED	__CDADD
;	8バイト浮動小数点数どうしの加算をします。
;<(sp).d:被加算数の8バイト浮動小数点数
;<(8,sp).d:加算数の8バイト浮動小数点数
;>(sp).d:演算結果の8バイト浮動小数点数
;>c-flag:cs=エラー
;>v-flag:(cs)vs=オーバーフロー,(cs)vc=アンダーフロー
fe_cdadd::
	param	a6
	fmove.l	#$00000000,fpsr
	fmove.d	(a6)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fadd.d	(a6),fp0
	fmove.d	fp0,-(a6)
	fmove.l	fpsr,d7
	and.b	#i|v|u|0|0|0|0|0,d7	;ivu00000
	bne	@f
	exit

@@:	add.b	d7,d7			;vu000000
	rol.b	#2,d7			;000000vu
	or.b	#0|0|0|0|C,d7		;000000vc
	exit	D7

;----------------------------------------------------------------
;$FEEE	__CDSUB
;	8バイト浮動小数点数どうしの減算をします。
;<(sp).d:被減算数の8バイト浮動小数点数
;<(8,sp).d:減算数の8バイト浮動小数点数
;>(sp).d:演算結果の8バイト浮動小数点数
;>c-flag:cs=エラー
;>v-flag:(cs)vs=オーバーフロー,(cs)vc=アンダーフロー
fe_cdsub::
	param	a6
	fmove.l	#$00000000,fpsr
	fmove.d	(a6)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fsub.d	(a6),fp0
	fmove.d	fp0,-(a6)
	fmove.l	fpsr,d7
	and.b	#i|v|u|0|0|0|0|0,d7	;ivu00000
	bne	@f
	exit

@@:	add.b	d7,d7			;vu000000
	rol.b	#2,d7			;000000vu
	or.b	#0|0|0|0|C,d7		;000000vc
	exit	D7

;----------------------------------------------------------------
;$FEEF	__CDMUL
;	8バイト浮動小数点数どうしの乗算をします。
;<(sp).d:被乗算数の8バイト浮動小数点数
;<(8,sp).d:乗算数の8バイト浮動小数点数
;>(sp).d:演算結果の8バイト浮動小数点数
;>c-flag:cs=エラー
;>v-flag:(cs)vs=オーバーフロー,(cs)vc=アンダーフロー
fe_cdmul::
	param	a6
	fmove.l	#$00000000,fpsr
	fmove.d	(a6)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fmul.d	(a6),fp0
	fmove.d	fp0,-(a6)
	fmove.l	fpsr,d7
	and.b	#i|v|u|0|0|0|0|0,d7	;ivu00000
	bne	@f
	exit

@@:	add.b	d7,d7			;vu000000
	rol.b	#2,d7			;000000vu
	or.b	#0|0|0|0|C,d7		;000000vc
	exit	D7

;----------------------------------------------------------------
;$FEF0	__CDDIV
;	8バイト浮動小数点数どうしの除算をします。
;<(sp).d:被除算数の8バイト浮動小数点数
;<(8,sp).d:除算数の8バイト浮動小数点数
;>(sp).d:演算結果の8バイト浮動小数点数
;>c-flag:cs=エラー
;>z-flag:(cs)eq=0で割った
;>v-flag:(cs,ne)vs=オーバーフロー,(cs,ne)vc=アンダーフロー
fe_cddiv::
	param	a6
	fmove.l	#$00000000,fpsr
	fmove.d	(a6)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fdiv.d	(a6),fp0
	fmove.d	fp0,-(a6)
	fmove.l	fpsr,d7
	and.b	#i|v|u|z|0|0|0|0,d7	;ivuz0000
	bne	@f
	exit

@@:	add.b	d7,d7			;vuz00000
	rol.b	#2,d7			;z00000vu
	bpl	@f
	addq.b	#4,d7			;z0000zvu
@@:	or.b	#0|0|0|0|C,d7		;z0000zvc
	exit	D7

;----------------------------------------------------------------
;$FEF1	__CDMOD
;	8バイト浮動小数点数どうしの剰余を求めます。
;<(sp).d:被除算数の8バイト浮動小数点数
;<(8,sp).d:除算数の8バイト浮動小数点数
;>(sp).d:演算結果の8バイト浮動小数点数
;>c-flag:cs=エラー
;>z-flag:(cs)eq=0で割った
;>v-flag:(cs,ne)vs=有効数字の範囲外,(cs,ne)vc=アンダーフロー
fe_cdmod::
	param	a6
	move.l	(8,a6),d7
	add.l	d7,d7
	or.l	(8+4,a6),d7
	beq	1f
	fmove.l	#$00000000,fpsr
	fmove.d	(a6)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fmod.d	(a6),fp0		;エミュレーション
	fmove.d	fp0,-(a6)
	fmove.l	fpsr,d7
	and.b	#i|v|u|z|0|0|0|0,d7	;ivuz0000
	bne	@f
	exit

@@:	add.b	d7,d7			;vuz00000
	rol.b	#2,d7			;z00000vu
	bpl	@f
	addq.b	#4,d7			;z0000zvu
@@:	or.b	#0|0|0|0|C,d7		;z0000zvc
	exit	D7

1:	move.l	#$7FFFFFFF,(a6)+
	move.l	#$FFFFFFFF,(a6)
	exit	C,Z

;----------------------------------------------------------------
;$FEF2	__CFCMP
;	4バイト浮動小数点数どうしの比較をします。
;<(sp).s:被比較数
;<(4,sp).s:比較数
;	被比較数から比較数を減算した結果にしたがってセットされます。
;>n-flag:mi=負
;>z-flag:eq=0
;>c-flag:cs=ボローが発生した
;	被比較数が比較数より大きいとき	cc,ne,pl
;	被比較数が比較数と等しいとき	cc,eq,pl
;	被比較数が比較数より小さいとき	cs,ne,mi
fe_cfcmp::
	param	a6
	move.l	(a6)+,d7
	bmi	1f
	tst.l	(a6)
	bmi	2f
	cmp.l	(a6),d7
	exit	ccr

1:	move.l	(a6),d7
	bpl	3f
	cmp.l	-(a6),d7
	exit	ccr

2:	exit	_

3:	exit	C,N

;----------------------------------------------------------------
;$FEF3	__CFADD
;	4バイト浮動小数点数どうしの加算をします。
;<(sp).s:被加算数
;<(4,sp).s:加算数
;>(sp).s:演算結果
;>c-flag:cs=エラー
;>v-flag:(cs)vs=オーバーフロー,(cs)vc=アンダーフロー
fe_cfadd::
	param	a6
	fmove.l	#$00000000,fpsr
	fmove.s	(a6)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fadd.s	(a6),fp0
	fmove.s	fp0,-(a6)
	fmove.l	fpsr,d7
	and.b	#i|v|u|0|0|0|0|0,d7	;ivu00000
	bne	@f
	exit

@@:	add.b	d7,d7			;vu000000
	rol.b	#2,d7			;000000vu
	or.b	#0|0|0|0|C,d7		;000000vc
	exit	D7

;----------------------------------------------------------------
;$FEF4	__CFSUB
;	4バイト浮動小数点数どうしの減算をします。
;<(sp).s:被減算数
;<(4,sp).s:減算数
;>(sp).s:演算結果
;>c-flag:cs=エラー
;>v-flag:(cs)vs=オーバーフロー,(cs)vc=アンダーフロー
fe_cfsub::
	param	a6
	fmove.l	#$00000000,fpsr
	fmove.s	(a6)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fsub.s	(a6),fp0
	fmove.s	fp0,-(a6)
	fmove.l	fpsr,d7
	and.b	#i|v|u|0|0|0|0|0,d7	;ivu00000
	bne	@f
	exit

@@:	add.b	d7,d7			;vu000000
	rol.b	#2,d7			;000000vu
	or.b	#0|0|0|0|C,d7		;000000vc
	exit	D7

;----------------------------------------------------------------
;$FEF5	__CFMUL
;	4バイト浮動小数点数どうしの乗算をします。
;<(sp).s:被乗算数
;<(4,sp).s:乗算数
;>(sp).s:演算結果
;>c-flag:cs=エラー
;>v-flag:(cs)vs=オーバーフロー,(cs)vc=アンダーフロー
fe_cfmul::
	param	a6
	fmove.l	#$00000000,fpsr
	fmove.s	(a6)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fsglmul.s	(a6),fp0
	fmove.s	fp0,-(a6)
	fmove.l	fpsr,d7
	and.b	#i|v|u|0|0|0|0|0,d7	;ivu00000
	bne	@f
	exit

@@:	add.b	d7,d7			;vu000000
	rol.b	#2,d7			;000000vu
	or.b	#0|0|0|0|C,d7		;000000vc
	exit	D7

;----------------------------------------------------------------
;$FEF6	__CFDIV
;	4バイト浮動小数点数どうしの除算をします。
;<(sp).s:被除算数
;<(4,sp).s:除算数
;>(sp).s:演算結果
;>c-flag:cs=エラー
;>z-flag:(cs)eq=0で割った
;>v-flag:(cs,ne)vs=オーバーフロー,(cs,ne)vc=アンダーフロー
fe_cfdiv::
	param	a6
	fmove.l	#$00000000,fpsr
	fmove.s	(a6)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fsgldiv.s	(a6),fp0
	fmove.s	fp0,-(a6)
	fmove.l	fpsr,d7
	and.b	#i|v|u|z|0|0|0|0,d7	;ivuz0000
	bne	@f
	exit

@@:	add.b	d7,d7			;vuz00000
	rol.b	#2,d7			;z00000vu
	bpl	@f
	addq.b	#4,d7			;z0000zvu
@@:	or.b	#0|0|0|0|C,d7		;z0000zvc
	exit	D7

;----------------------------------------------------------------
;$FEF7	__CFMOD
;	4バイト浮動小数点数どうしの剰余を求めます。
;<(sp).s:被除算数
;<(4,sp).s:除算数
;>(sp).s:演算結果
;>c-flag:cs=エラー
;>z-flag:(cs)eq=0で割った
;>v-flag:(cs,ne)vs=有効数字の範囲外,(cs,ne)vc=アンダーフロー
fe_cfmod::
	param	a6
	tst.l	4(a6)
	beq	1f
	fmove.l	#$00000000,fpsr
	fmove.s	(a6)+,fp0
		clr.b	4*2+1(sp)	;CCRクリア
	fmod.s	(a6),fp0		;エミュレーション
	fmove.s	fp0,-(a6)
	fmove.l	fpsr,d7
	and.b	#i|v|u|z|0|0|0|0,d7	;ivuz0000
	bne	@f
	exit

@@:	add.b	d7,d7			;vuz00000
	rol.b	#2,d7			;z00000vu
	bpl	@f
	addq.b	#4,d7			;z0000zvu
@@:	or.b	#0|0|0|0|C,d7		;z0000zvc
	exit	D7

1:	move.l	#$7FFFFFFF,(a6)
	exit	C,Z

;----------------------------------------------------------------
;$FEF8	__CDTST
;	8バイト浮動小数点数と0の比較をします。
;<(sp).d:8バイト浮動小数点数
;>z-flag:eq=0
;>n-flag:mi=負
fe_cdtst::
	param	a6
	move.l	(a6)+,d7
	or.w	(a6)+,d7
	or.w	(a6),d7
	tst.l	d7
	exit	ccr

;----------------------------------------------------------------
;$FEF9	__CFTST
;	4バイト浮動小数点数と0の比較をします。
;<(sp).s:4バイト浮動小数点数
;>z-flag:eq=0
;>n-flag:mi=負
fe_cftst::
	param	a6
	cmpi.l	#$80000000,(a6)
	beq	@f
	tst.l	(a6)
@@:	exit	ccr

;----------------------------------------------------------------
;$FEFA	__CDINC
;	8バイト浮動小数点数に1を加えます。
;<(sp).d:8バイト浮動小数点数
;>(sp).d:演算結果
fe_cdinc::
	param	a6
	fmove.d	(a6),fp0
	fadd.s	#0f1,fp0
	fmove.d	fp0,(a6)
	exit

;----------------------------------------------------------------
;$FEFB	__CFINC
;	4バイト浮動小数点数に1を加えます。
;<(sp).s:4バイト浮動小数点数
;>(sp).s:演算結果
fe_cfinc::
	param	a6
	fmove.s	(a6),fp0
	fadd.s	#0f1,fp0
	fmove.s	fp0,(a6)
	exit

;----------------------------------------------------------------
;$FEFC	__CDDEC
;	8バイト浮動小数点数から1を引きます。
;<(sp).d:8バイト浮動小数点数
;>(sp).d:演算結果
fe_cddec::
	param	a6
	fmove.d	(a6),fp0
	fsub.s	#0f1,fp0
	fmove.d	fp0,(a6)
	exit

;----------------------------------------------------------------
;$FEFD	__CFDEC
;	4バイト浮動小数点数から1を引きます。
;<(sp).s:4バイト浮動小数点数
;>(sp).s:演算結果
fe_cfdec::
	param	a6
	fmove.s	(a6),fp0
	fsub.s	#0f1,fp0
	fmove.s	fp0,(a6)
	exit

;----------------------------------------------------------------
;$FEFE	__FEVARG
;	組み込まれている数値演算デバイスドライバの種類を照会します。
;	組み込まれている数値演算デバイスドライバにより次に示す値が返ります。
;FLOAT1.Xの場合
;>d0.l:'HS86'($48533836)
;>d1.l:'SOFT'($534F4654)
;FLOAT2.Xの場合
;>d0.l:'IEEE'($49454545)
;>d1.l:'SOFT'($534F4654)
;FLOAT3.Xの場合
;>d0.l:'IEEE'($49454545)
;>d1.l:'FPCP'($46504350)
;FLOAT4.Xの場合
;>d0.l:'IEEE'($49454545)
;>d1.l:'FP20'($46503230)
fe_fevarg::
	move.l	#'IEEE',d0
	move.l	#'FPSP',d1
	exit

;----------------------------------------------------------------
;$FEFF	__FEVECS
;	浮動小数点演算処理の追加、変更。
;<d0.l:FETBLの番号
;<a0.l:処理アドレス
;>d0.l:前の処理アドレス
;	引数のd0の値は$FE00~$FEFEの範囲です。
;	これ以外の値を渡すとd0に-1を返します。
fe_fevecs::
	moveq.l	#-1,d0
	exit

;----------------------------------------------------------------
;定数
pi:
	.dc.x	!40000000C90FDAA22168C235	;cr($00)=π
one:
	.dc.x	!3FFF00008000000000000000	;cr($32)=10^0

;	.dc.x	!40000000C90FDAA22168C235	;π
;	.dc.x	!3FFD0000A2F9836E4E44152A	;1/π
;	.dc.x	!3FFD00009A209A84FBCFF798	;log10(2)
;	.dc.x	!40000000D49A784BCD1B8AFF	;1/log10(2)
;	.dc.x	!40000000ADF85458A2BB4A9A	;e
;	.dc.x	!3FFD0000BC5AB1B16779BE36	;1/e
;	.dc.x	!3FFF0000B8AA3B295C17F0BC	;log2(e)
;	.dc.x	!3FFE0000B17217F7D1CF79AC	;1/log2(e)
;	.dc.x	!3FFD0000DE5BD8A937287195	;log10(e)
;	.dc.x	!40000000935D8DDDAAA8AC17	;1/log10(e)
;	.dc.x	!000000000000000000000000	;0
;	.dc.x	!3FFE0000B17217F7D1CF79AC	;ln(2)
;	.dc.x	!3FFF0000B8AA3B295C17F0BC	;1/ln(2)
;	.dc.x	!40000000935D8DDDAAA8AC17	;ln(10)
;	.dc.x	!3FFD0000DE5BD8A937287195	;1/ln(10)
;	.dc.x	!3FFF00008000000000000000	;10^0
;	.dc.x	!3FFF00008000000000000000	;10^-0
;	.dc.x	!40020000A000000000000000	;10^1
;	.dc.x	!3FFB0000CCCCCCCCCCCCCCCD	;10^-1
;	.dc.x	!40050000C800000000000000	;10^2
;	.dc.x	!3FF80000A3D70A3D70A3D70A	;10^-2
;	.dc.x	!400C00009C40000000000000	;10^4
;	.dc.x	!3FF10000D1B71758E219652C	;10^-4
;	.dc.x	!40190000BEBC200000000000	;10^8
;	.dc.x	!3FE40000ABCC77118461CEFD	;10^-8
;	.dc.x	!403400008E1BC9BF04000000	;10^16
;	.dc.x	!3FC90000E69594BEC44DE15B	;10^-16
;	.dc.x	!406900009DC5ADA82B70B59E	;10^32
;	.dc.x	!3F940000CFB11EAD453994BA	;10^-32
;	.dc.x	!40D30000C2781F49FFCFA6D5	;10^64
;	.dc.x	!3F2A0000A87FEA27A539E9A5	;10^-64
;	.dc.x	!41A8000093BA47C980E98CE0	;10^128
;	.dc.x	!3E550000DDD0467C64BCE4A0	;10^-128
;	.dc.x	!43510000AA7EEBFB9DF9DE8E	;10^256
;	.dc.x	!3CAC0000C0314325637A193A	;10^-256
;	.dc.x	!46A30000E319A0AEA60E91C7	;10^512
;	.dc.x	!395A00009049EE32DB23D21C	;10^-512
;	.dc.x	!4D480000C976758681750C17	;10^1024
;	.dc.x	!32B50000A2A682A5DA57C0BE	;10^-1024
;	.dc.x	!5A9200009E8B3B5DC53D5DE5	;10^2048
;	.dc.x	!256B0000CEAE534F34362DE4	;10^-2048
;	.dc.x	!75250000C46052028A20979B	;10^4096
;	.dc.x	!0AD80000A6DD04C8D2CE9FDE	;10^-4096
;	.dc.x	!3FFF00008000000000000000	;10^0
;	.dc.x	!40020000A000000000000000	;10^1
;	.dc.x	!40050000C800000000000000	;10^2
;	.dc.x	!40080000FA00000000000000	;10^3
;	.dc.x	!400C00009C40000000000000	;10^4
;	.dc.x	!400F0000C350000000000000	;10^5
;	.dc.x	!40120000F424000000000000	;10^6
;	.dc.x	!401600009896800000000000	;10^7
;	.dc.x	!40190000BEBC200000000000	;10^8
;	.dc.x	!401C0000EE6B280000000000	;10^9
;	.dc.x	!402000009502F90000000000	;10^10
;	.dc.x	!40230000BA43B74000000000	;10^11
;	.dc.x	!40260000E8D4A51000000000	;10^12
;	.dc.x	!402A00009184E72A00000000	;10^13
;	.dc.x	!402D0000B5E620F480000000	;10^14
;	.dc.x	!40300000E35FA931A0000000	;10^15
;	.dc.x	!403400008E1BC9BF04000000	;10^16
;	.dc.x	!40370000B1A2BC2EC5000000	;10^17
;	.dc.x	!403A0000DE0B6B3A76400000	;10^18
;	.dc.x	!403E00008AC7230489E80000	;10^19
;	.dc.x	!40410000AD78EBC5AC620000	;10^20
;	.dc.x	!40440000D8D726B7177A8000	;10^21
;	.dc.x	!40480000878678326EAC9000	;10^22
;	.dc.x	!404B0000A968163F0A57B400	;10^23
;	.dc.x	!404E0000D3C21BCECCEDA100	;10^24
;	.dc.x	!4052000084595161401484A0	;10^25
;	.dc.x	!40550000A56FA5B99019A5C8	;10^26
;	.dc.x	!40580000CECB8F27F4200F3A	;10^27
;	.dc.x	!405C0000813F3978F8940984	;10^28
;	.dc.x	!405F0000A18F07D736B90BE5	;10^29
;	.dc.x	!40620000C9F2C9CD04674EDE	;10^30
;	.dc.x	!40650000FC6F7C4045812296	;10^31
;	.dc.x	!406900009DC5ADA82B70B59E	;10^32
;	.dc.x	!406C0000C5371912364CE306	;10^33
;	.dc.x	!406F0000F684DF56C3E01BC8	;10^34
;	.dc.x	!407300009A130B963A6C115D	;10^35
;	.dc.x	!40760000C097CE7BC90715B4	;10^36
;	.dc.x	!40790000F0BDC21ABB48DB21	;10^37
;	.dc.x	!407D000096769950B50D88F5	;10^38
;	.dc.x	!40800000BC143FA4E250EB32	;10^39
;	.dc.x	!40830000EB194F8E1AE525FE	;10^40
;	.dc.x	!4087000092EFD1B8D0CF37BF	;10^41
;	.dc.x	!408A0000B7ABC627050305AF	;10^42
;	.dc.x	!408D0000E596B7B0C643C71B	;10^43
;	.dc.x	!409100008F7E32CE7BEA5C71	;10^44
;	.dc.x	!40940000B35DBF821AE4F38D	;10^45
;	.dc.x	!40970000E0352F62A19E3070	;10^46
;	.dc.x	!409B00008C213D9DA502DE46	;10^47
;	.dc.x	!409E0000AF298D050E4395D8	;10^48
;	.dc.x	!40A10000DAF3F04651D47B4E	;10^49
;	.dc.x	!40A5000088D8762BF324CD11	;10^50
;	.dc.x	!40A80000AB0E93B6EFEE0055	;10^51
;	.dc.x	!40AB0000D5D238A4ABE9806A	;10^52
;	.dc.x	!40AF000085A36366EB71F042	;10^53
;	.dc.x	!40B20000A70C3C40A64E6C52	;10^54
;	.dc.x	!40B50000D0CF4B50CFE20766	;10^55
;	.dc.x	!40B9000082818F1281ED44A0	;10^56
;	.dc.x	!40BC0000A321F2D7226895C8	;10^57
;	.dc.x	!40BF0000CBEA6F8CEB02BB3A	;10^58
;	.dc.x	!40C20000FEE50B7025C36A08	;10^59
;	.dc.x	!40C600009F4F2726179A2245	;10^60
;	.dc.x	!40C90000C722F0EF9D80AAD6	;10^61
;	.dc.x	!40CC0000F8EBAD2B84E0D58C	;10^62
;	.dc.x	!40D000009B934C3B330C8578	;10^63
;	.dc.x	!3FFF00008000000000000000	;10^-0
;	.dc.x	!3FFB0000CCCCCCCCCCCCCCCD	;10^-1
;	.dc.x	!3FF80000A3D70A3D70A3D70A	;10^-2
;	.dc.x	!3FF5000083126E978D4FDF3B	;10^-3
;	.dc.x	!3FF10000D1B71758E219652B	;10^-4
;	.dc.x	!3FEE0000A7C5AC471B478422	;10^-5
;	.dc.x	!3FEB00008637BD05AF6C69B5	;10^-6
;	.dc.x	!3FE70000D6BF94D5E57A42BB	;10^-7
;	.dc.x	!3FE40000ABCC77118461CEFC	;10^-8
;	.dc.x	!3FE1000089705F4136B4A596	;10^-9
;	.dc.x	!3FDD0000DBE6FECEBDEDD5BD	;10^-10
;	.dc.x	!3FDA0000AFEBFF0BCB24AAFE	;10^-11
;	.dc.x	!3FD700008CBCCC096F5088CB	;10^-12
;	.dc.x	!3FD30000E12E13424BB40E12	;10^-13
;	.dc.x	!3FD00000B424DC35095CD80E	;10^-14
;	.dc.x	!3FCD0000901D7CF73AB0ACD8	;10^-15
;	.dc.x	!3FC90000E69594BEC44DE15A	;10^-16
;	.dc.x	!3FC60000B877AA3236A4B448	;10^-17
;	.dc.x	!3FC300009392EE8E921D5D06	;10^-18
;	.dc.x	!3FBF0000EC1E4A7DB69561A3	;10^-19
;	.dc.x	!3FBC0000BCE5086492111AE9	;10^-20
;	.dc.x	!3FB90000971DA05074DA7BEE	;10^-21
;	.dc.x	!3FB50000F1C90080BAF72CB0	;10^-22
;	.dc.x	!3FB20000C16D9A0095928A26	;10^-23
;	.dc.x	!3FAF00009ABE14CD44753B52	;10^-24
;	.dc.x	!3FAB0000F79687AED3EEC550	;10^-25
;	.dc.x	!3FA80000C612062576589DDA	;10^-26
;	.dc.x	!3FA500009E74D1B791E07E48	;10^-27
;	.dc.x	!3FA10000FD87B5F28300CA0D	;10^-28
;	.dc.x	!3F9E0000CAD2F7F5359A3B3E	;10^-29
;	.dc.x	!3F9B0000A2425FF75E14FC32	;10^-30
;	.dc.x	!3F98000081CEB32C4B43FCF5	;10^-31
;	.dc.x	!3F940000CFB11EAD453994BB	;10^-32
;	.dc.x	!3F910000A6274BBDD0FADD62	;10^-33
;	.dc.x	!3F8E000084EC3C97DA624AB5	;10^-34
;	.dc.x	!3F8A0000D4AD2DBFC3D07788	;10^-35
;	.dc.x	!3F870000AA242499697392D3	;10^-36
;	.dc.x	!3F840000881CEA14545C7576	;10^-37
;	.dc.x	!3F800000D9C7DCED53C72256	;10^-38
;	.dc.x	!3F7D0000AE397D8AA96C1B78	;10^-39
;	.dc.x	!3F7A00008B61313BBABCE2C6	;10^-40
;	.dc.x	!3F760000DF01E85F912E37A3	;10^-41
;	.dc.x	!3F730000B267ED1940F1C61C	;10^-42
;	.dc.x	!3F7000008EB98A7A9A5B04E3	;10^-43
;	.dc.x	!3F6C0000E45C10C42A2B3B05	;10^-44
;	.dc.x	!3F690000B6B00D69BB55C8D1	;10^-45
;	.dc.x	!3F6600009226712162AB070E	;10^-46
;	.dc.x	!3F620000E9D71B689DDE71B0	;10^-47
;	.dc.x	!3F5F0000BB127C53B17EC15A	;10^-48
;	.dc.x	!3F5C000095A8637627989AAE	;10^-49
;	.dc.x	!3F580000EF73D256A5C0F77D	;10^-50
;	.dc.x	!3F550000BF8FDB78849A5F97	;10^-51
;	.dc.x	!3F520000993FE2C6D07B7FAC	;10^-52
;	.dc.x	!3F4E0000F53304714D9265E0	;10^-53
;	.dc.x	!3F4B0000C428D05AA4751E4D	;10^-54
;	.dc.x	!3F4800009CED737BB6C4183E	;10^-55
;	.dc.x	!3F440000FB158592BE068D30	;10^-56
;	.dc.x	!3F410000C8DE047564D20A8D	;10^-57
;	.dc.x	!3F3E0000A0B19D2AB70E6ED7	;10^-58
;	.dc.x	!3F3B0000808E17555F3EBF12	;10^-59
;	.dc.x	!3F370000CDB02555653131B6	;10^-60
;	.dc.x	!3F340000A48CEAAAB75A8E2B	;10^-61
;	.dc.x	!3F31000083A3EEEEF9153E89	;10^-62
;	.dc.x	!3F2D0000D29FE4B18E88640E	;10^-63