*** ceil.s
* 	Double Precision Ceiling Function
*	for Alcyon C
*
*	double ceil(d)
*	double d;
*
*	Copyright Atari Corp. 1987,1988
*
*	MDJohnson       2/15/88
***

	.include fpmacro

; ceil(x)
	fpinit	ceil
	fpidle				; wait for idle state
;
; This procedure looks like this:
;
;	fp0 = INRZ(arg);
;	if ((fp0 >= 0) && (fp0 != arg)) fp0 += 1;
;	return fp0;
;
; It is coded the way it is to use only one FP register.
;

	move.w	#$5403,FPCMD		; fp0 = intrz(x) (round to zero)
	ckcir	#$9608			; ready for double
	move.l	4(sp),FPOP		; write first half
	move.l	8(sp),FPOP		; write second half

	fpidle				; wait for idle state
	btst.b	#3,FPCCR		; negative?
	bne.s	.getans			; yes, done.

	move.w	#$5438,FPCMD		; FCMP #data,fp0
	ckcir	#$9608			; ready for double
	move.l	4(sp),FPOP		; write double
	move.l	8(sp),FPOP

	fpidle
	btst.b	#2,FPCCR		; zero? (intrz(x) == x)
	bne.s	.getans			; yes, done.

	move.w	#$5022,FPCMD		; else fp0 += 1
	ckcir	#$9502			; ready for int
	move.w	#1,FPOP

.getans:
	fpidle				; wait for idle state
	move.w	#$7400,FPCMD		; fp0 -> double
	ckcir	#$B208			; ready for double
	move.l	FPOP,d0			; get double
	move.l	FPOP,d1
	rts

