	section	ffpConvert,CODE
	IDNT	ALL

**	ffpConvert
**		for doing FFP conversions from within Macro68
**
**		Copyright ©1990 DigiSoft
**
**	Permission is granted to purchasers of Macro68 to modify this source
**	file.  Permission is further granted to distribute the source code that
**	they have modified subject to the following conditions:
**	1.  That the original, unaltered, source is included with the
**	    distribution.
**	2.  That no charge is made for the distribution, other than the cost of
**	    media.                    (Distribution via Fred Fish is permitted)
**	3.  That my copyright notice remains as part of this and any other
**	    file adapted from this file.
**                                               Paul Coward
**                                                         DigiSoft
**
**	Tabstops : 8
**	Assemble with Macro68


**	 3-07-90	** written


* NOTES:
*
*	This program will convert a decimal number into the Motorola Fast Floating
* Point (FFP) equivilent.
*	The given number may not exceed 4,294,967,295
*	The given number can have up to 9 digits to the right of the decimal point.
*	These limitations are ok for the use that I wanted, and for the purposes of
* a demonstration.  If anyone wants full FFP support then I suggest that you use
* this source as a reference to write a parser making full use of the FFP library.



		OBJFILE		"ram:ffpConvert"
	;	ERRORFILE	"ram:ffpConvert.bugs"

	;	PALL
	;	HALL
		EXEOBJ
	;	LIST
	;	LISTSYMS
	;	ADDSYM
	;	LISTFILE	"ram:ffpConvert.lst"
	;	CREFFILE	"ram:ffpConvert.cref"
	;	DEBUG
	;	REALTIME
		STRICT


	ifnd	EXEC_TYPES_I			;defined in my sticky maclib file
	if1
	PRINTX	Resident maclib not in use.
	endc
_AbsExecBase		equ	4
_LVOAlert		equ	-108	;exec
_LVOCloseLibrary	equ	-414	;exec
_LVOForbid		equ	-132	;exec
_LVOOpenLibrary		equ	-552	;exec
_LVOPermit		equ	-138	;exec
_LVOSPAdd		equ	-66
_LVOSPDiv		equ	-84
_LVOSPFlt		equ	-36
AT_Recovery		equ	$00000000
AG_OpenLib		equ	$00030000
	endc


_LVOdsAllocCPremember	equ	-30
_LVOdsAllocScratch	equ	-42
_LVOdsClearRemember	equ	-66
_LVOdsFreeScratch	equ	-174
_LVOdsGetDecimal	equ	-180
_LVOdsParse		equ	-216
_LVOdsPuts		equ	-648
_LVOdsSPAdd		equ	-66
_LVOdsSPDiv		equ	-84
_LVOdsSPFlt		equ	-36
_LVOdsXlateHexLong	equ	-390


	ifnd	csd_Output
CALL	MACRO			;library vector / <library base>
	IFGT	NARG-1
	pushm	d1/a0-a1/a6
	movea.l	(csd_\2Base,a5),a6
	jsr	(_LVO\1,a6)
	popm	d1/a0-a1/a6
	ELSE
	pushm	d1/a0-a1
	jsr	(_LVO\1,a6)
	popm	d1/a0-a1
	ENDC
	ENDM

csd_DSSBase		equ	16
csd_Output		equ	20*4
csd_MathBase		equ	36
AO_DSSLib		equ	$00008099	;alert number id support library can't be opened
Tab			equ	$09
Lf			equ	$0a
CSI			equ	$9b
	endc


csd_RememberKey		equ	84	
csd_Args		equ	88		;8 bytes required
csd_PrintBuffer		equ	96
csd_SIZEOF		equ	106


Release			equ	'1.0 '
VerNo			equ	'0.01'

*************************
*	COLD ENTRY	*
*************************


START:		moveq		#0,d3
		move.l		a0,d6
		move.l		d0,d7
		movea.l		(_AbsExecBase).w,a6	;establish exec for calls

	; --- open the support library

		moveq		#2,d0			;version #
		lea	 	(supportLibName,pc),a1	;point to liberary name
		jsr		(_LVOOpenLibrary,a6)	;exec
		tst.l		d0
		bne.b		1$
		move.l		#AT_Recovery!AG_OpenLib!AO_DSSLib,d7
		jsr		(_LVOAlert,a6)
		bra		exitWithError

	; --- initialize the scratch area

1$		movea.l		d0,a6
		moveq		#csd_SIZEOF,d0
		moveq		#33,d1
		moveq		#(1<<4),d2
		jsr		(_LVOdsAllocScratch,a6)
		bne		exitWithError

	; --- initialize the argument pointers

		movem.l		d6-d7,(csd_Args,a5)	;& a_Length(A0)

	; --- display banner (if possible)

		tst.l		(csd_Output,a5)
		beq.b		.noOutput
		lea		(Title,pc),a1
		jsr		(_LVOdsPuts,a6)

	; --- parse args

.noOutput:	lea		(csd_RememberKey,a5),a0
		move.l		#256,d0
		jsr		(_LVOdsAllocCPremember,a6)
		move.l		d0,(ArgPointers).l
		beq		exitWithError

		lea		(csd_Args,a5),a0
		lea		(additionalHelp,pc),a1
		lea		(ArgPointers+4,pc),a2
		lea		(CmdTemplate,pc),a3
		jsr		(_LVOdsParse,a6)
		bpl.b		doIt
		movea.l		(ArgPointers,pc),a1
		jsr		(_LVOdsPuts,a6)
		lea		(csd_RememberKey,a5),a0
		jsr		(_LVOdsClearRemember,a6)
		bra		exitWithError

	; --- any args ?

doIt:		move.l		(number,pc),d1
		beq		exitWithError
		moveq		#0,d4			;initialize decimal point counter
		movea.l		d1,a0
		jsr		(_LVOdsGetDecimal,a6)	;read the number
		beq		exitWithError
		CALL		SPFlt,Math
		move.l		d0,d6			;save the number (FFP)
		cmpi.b		#'.',(a0)+		;failed on decimal point ?
		bne.b		.noFraction

	; --- there is a decimal fraction on this number - yuk! - more work
	; --- calcutate a power of 10 to apply to the fractional part of the
	; -- number.

		move.l		a0,d2
.strlen:	tst.b		(a0)+
		bne.b		.strlen
		exg		a0,d2
		sub.l		a0,d2			;number of decimal places
		subq.l		#1,d2			;compensate for null term
		bmi.b		.noFraction
		cmpi.l		#9,d2			;max decimal places exceeded ?
		bhi		exitWithError		;yes
		lea		(Power_Of_10_Table,pc),a1
		lsl.l		#2,d2			;longword index
		move.l		(-4,a1,d2.w),d4		;power of 10 to apply to fraction

	; --- pick up the fraction

		jsr		(_LVOdsGetDecimal,a6)
		beq		exitWithError
		CALL		SPFlt,Math
		move.l		d0,d5			;save fractional number (FFP)
		move.l		d4,d0			;decimal power of 10
		CALL		SPFlt,Math
		move.l		d0,d1			;decimal power of 10 (FFP)
		move.l		d5,d0			;fractional number (FFP)
		CALL		SPDiv,Math
		bvs		exitWithError
		move.l		d6,d1			;whole number (FFP)
		CALL		SPAdd,Math
		bvs		exitWithError
		move.l		d0,d6			;result (FFP)

	; --- print the result if we have been run from a CLI

.noFraction:	tst.l		(csd_Output,a5)
		beq.b		EXIT
		move.l		d6,d0
		lea		(csd_PrintBuffer,a5),a0
		move.b		#Lf,(a0)+
		move.b		#'$',(a0)+
		jsr		(_LVOdsXlateHexLong,a6)
		move.b		#Lf,(a0)+
		clr.b		(a0)
		lea		(csd_PrintBuffer,a5),a1
		jsr		(_LVOdsPuts,a6)

EXIT:		lea		(csd_RememberKey,a5),a0
		jsr		(_LVOdsClearRemember,a6)
		jsr		(_LVOdsFreeScratch,a6)
		movea.l		a6,a1
		movea.l		(4).w,a6
		jsr		(_LVOCloseLibrary,a6)
		move.l		d6,d0			;return the result
		rts					;exit to DOS


	; --- error detected during start - exit gracefully
	; --- This program uses -1 as an error exit condition.  This means
	; -- that FFP value $ffffffff can not be returned.  This is a minor
	; -- inconvienance against the ability to be able to check for an
	; -- error return condition in macro68.

exitWithError:	moveq		#-1,d6
		bra		EXIT


***************************************
***************************************
***************************************


ArgPointers:	dl	0
number:		dl	0		;pointer to decimal format ascii string


CmdTemplate:
	cstr	'NUMBER/A'


additionalHelp:
	db	'USAGE:',Lf
	cstr	'ffpConvert <number>',Lf,Lf


***************************************
***************************************
***************************************


supportLibName:
	cstr	'digisoftSupport.library'
macro68LibName:
	cstr	'macro68.library'


	oddok
Title:	db	CSI,$35,';',$33,$33,'m'			;set graphic rendition
	db	'ffpConvert  '
	db	'Release '
	dl	Release
	db	'  Vers '
	dl	VerNo
	db	' CopyRight ©1990 DIGISOFT',Lf
	db	CSI,$30,';',$33,$31,'m'			;reset graphic rendition
	db	'  12 Dinmore St.  Moorooka 4105  Brisbane, QLD  Australia',Lf
	db	'       Phone  ISD (617) 277-3255  STD (07) 277-3255'
	db	0
	odderror


	quad
Power_Of_10_Table:
	dl	10
	dl	100
	dl	1000
	dl	10000
	dl	100000
	dl	1000000
	dl	10000000
	dl	100000000
	dl	1000000000


*******************************************************************************

	END
