	load	'macros.dump'
	include 'driver.equ'
	include 'scrap.equ'
	include 'sssc.equ'

	IMPORT	D_AddStrings
	IMPORT	D_AlertBox
	import	X_AWFormulaTable
	IMPORT	D_BeachBall
	IMPORT	D_CurCursor
	IMPORT	X_CurrentCell
	IMPORT	X_CurrentColumn
	IMPORT	X_CurrentFormat
	IMPORT	X_CurrentRow
	IMPORT	X_CurrentSize
	IMPORT	D_GrowHandle
	IMPORT	D_Message1
	IMPORT	D_Message2
	IMPORT	D_MessageThere
	IMPORT	D_NeedHand
	IMPORT	X_NumberStr
	IMPORT	X_OldCursor
	IMPORT	X_FormatValue
	IMPORT	D_SetCursor
	IMPORT	X_StandardDecimals
	IMPORT	X_StandardJust
	IMPORT	X_StandardProtection
	IMPORT	X_StandardVForm
	IMPORT	D_StringBuffer
	IMPORT	D_StringBuffer2
	IMPORT	X_tenthsto80ths
	import	X_ClipData
	IMPORT	D_SystemHandle
	import	D_Deref
	import	D_CheckPurge

	ENTRY	X_dotable

X_ScAWSStoSSScrap	PROC	EXPORT
	;Using X_SSScrapData
	;Using SaneEqus
	;Using D_OpenData
	;Using D_UtilData
	;Using X_ClipData
	;Using D_CursorData
	EXPORT	X_dotable

	input Src:l

	local Sptr:l,Soff:l,Dptr:l,Doff:l,Dsize:l
	local Messhand:l,Mptr:l,MaxBottom:w,MaxRight:w
	local CharsHand:l,Coldex:w,ChPtr:l,RealDptr:l
	local FormatLow:w,CurLevel:w,TempPtr:l,StrSize:w
	local TypeWord:w,Row:w,Column:w,AWCellSize:l
	local CellSize:l,Char:w,BeginLevel:w,TitleWord:w
	local Stack:w,SystemPtr:l,Parens:w,Func:w,Flen:w
	local Fptr:l,Acnt:w, Argptr:l,Aptr:l,Alen:l,A2len:l
	local Pptr:l,Pndx:w

	output Dest:l

	error err

	begin

	MoveWord >D_CurCursor,X_OldCursor

	stz err
	lda #0
	sta >D_MessageThere
	sta >D_Message1
	sta >D_Message1+2
	sta >D_Message2
	sta >D_Message2+2

;Get column widths - I need the originals for propogated labels
	SpaceLong
	PushLong #X_SSMessSize
	jsl D_NeedHand
	sta err
	PullLong MessHand
	jcs exit

	SpaceLong
	PushLong #254
	jsl D_NeedHand
	sta err
	PullLong CharsHand
	bcc ok1
	PushLong MessHand
	_Disposehandle
	brl exit

ok1	AddLong [MessHand],#X_SSMessColWidths,Mptr
	MoveLong [CharsHand],ChPtr
	AddLong [Src],#4,Sptr

	stz Coldex

colloop	jsl D_BeachBall
	lda Coldex
	cmp #127
	jge donecolloop

	asl a
	tay
	lda [Sptr]
	and #$ff
	sta [Chptr],y

	phy
	jsl X_tenthsto80ths
	ply
	sta [Mptr],y
	IncLong Sptr
	inc coldex
	brl colloop

donecolloop
;Now set up standard formats
	MoveLong [Src],Sptr

	ldy #X_AWLabelJust
	lda [Sptr],y
	and #%111
	cmp #2
	blt badlbljust
	cmp #5
	blt storelabel
badlbljust	lda #2
storelabel
	sta X_StandardJust

	ldy #X_AWValueFormat
	lda [Sptr],y
	and #%111
	cmp #2
	blt badvalform
notvalsmall	cmp #7
	blt storeval
badvalform	lda #6
storeval
	sta X_StandardVForm

	ldy #X_AWDecimals
	lda [Sptr],y
	and #%111		; got to be 0-7
storedecimals
	sta X_StandardDecimals

	ldy #X_AWProtected
	lda [Sptr],y
	and #$ff
	sta X_StandardProtection

;Get memory for scrap and set up all of the variables
	SpaceLong
	_MaxBlock
	PullLong Dsize

	SpaceLong
	PushLong Dsize
	jsl D_NeedHand
	sta err
	PullLong Dest
	bcc ok2
	PushLong MessHand
	_DisposeHandle
	PushLong CharsHand
	_DisposeHandle
	brl exit

ok2	Stzl Doff

	PushLong Src
	_HLock

	MoveLong [Src],Sptr

	MoveLong #X_SSScrapCells,Dsize
	jsr FixDptr
	MoveLong #10,Doff

	ldy #X_AWSSMinVers	; if MinVers is not zero, make sure
	lda [Sptr],y	;   we skip first two bytes of data (AW3.0)ÑJ.K.
	and #$00ff
	beq startdata

	Addwl #2,Sptr

startdata	AddLong Sptr,#X_AWSSHeaderSize,Sptr
	stz MaxBottom
	stz MaxRight

rowloop	jsl D_BeachBall

	lda [Sptr]
	cmp #-1
	jeq endoffile

	Addwl #2,Sptr
	lda [Sptr]
	sta Row

	cmp MaxBottom
	blt nomax
	sta MaxBottom

nomax	MoveWord #1,Column
	Addwl #2,Sptr

cellloop	jsl D_BeachBall
	lda [Sptr]

	and #$ff
	cmp #$80		; Does cell have data (127 bytes max)
	jlt cellthere
	cmp #$ff		; check end of row
	jeq endofrow

legal	and #$7f
	clc
	adc Column
	sta Column
	IncLong Sptr
	bra cellloop

endofrow
	MoveWord #1,Column
	IncLong Sptr
	brl rowloop

cellthere
	sta AWCellSize
	stz CellSize
	Stzl X_CurrentFormat
	lda Column
	cmp MaxRight
	blt nomax2
	sta MaxRight
nomax2	ldy #1
	lda [Sptr],y
	sta TypeWord
	MoveWord Row,X_CurrentRow
	MoveWord Column,X_CurrentColumn

	lda TypeWord
	and #$80
	jeq label

;*********************************************************************
;value

;Check for preformatted blank cell; D_Ignore this cell if it is
	lda TypeWord
	and #$40
	beq valuethere

	Addwl AWCellSize,Sptr
	IncLong Sptr
	inc Column
	brl cellloop

valuethere
	lda TypeWord
	and #$20
	jeq formula

	MoveWord #X_SSCellTypeValue,FormatLow
	bra doerror

formula	MoveWord #X_SSCellTypeFormula,FormatLow
	MoveWord #-1,CurLevel

doerror	lda TypeWord
	and #$4000
	beq doinval

	lda FormatLow
	ora #(X_SSCellInvalid+X_SSCellError)
	sta FormatLow
	bra X_dotable

doinval	lda TypeWord
	and #$2000
	beq X_dotable

	lda FormatLow
	ora #X_SSCellInvalid
	sta FormatLow

X_dotable	;
	lda TypeWord
	and #$0800		; check for Calculated Strings
	beq @X_Dotbl2
	
	jsr SetLabelJust
	bra endformat1

@X_Dotbl2	lda TypeWord
	xba
	and #$7
	sta X_CurrentFormat+2

	lda TypeWord
	and #$7
	asl a
	tax
	jmp (FormatTable1,x)

FormatTable1
	DC.W	error,Standard2,Fixed2,Dollars2,Commas2,Percent2,endformat1

error	brl exit

Standard2
	lda X_StandardDecimals
	sta X_CurrentFormat+2
	lda X_StandardVForm
	asl a
	tax
	jmp (FormatTable1,x)

Fixed2	lda FormatLow
	ora #X_SSCellFixed
	sta FormatLow
	brl endformat1

Dollars2	lda FormatLow
	ora #X_SSCellDollar
	ora #X_SSCellParenNeg
	sta FormatLow
	brl endformat1

Commas2	lda FormatLow
	ora #X_SSCellComma
	sta FormatLow
	brl endformat1

Percent2	lda FormatLow
	ora #X_SSCellPercent
	sta FormatLow

endformat1
	lda X_StandardProtection
	beq noprotect

	lda TypeWord
	and #$18
	cmp #$18
	bne noprotect
	lda X_CurrentFormat+2
	ora #X_SSCellProtect
	sta X_CurrentFormat+2

noprotect
	Addwls #3,Sptr
	PushLong #D_StringBuffer
	FD2X

	lda TypeWord
	and #$20
	bne noformula

	jsr doformula
	lda >D_StringBuffer2
	and #$ff
	inc a
	sta StrSize
	brl cont1

noformula
	SpaceWord
	SpaceLong
	SpaceWord
	PushWord #$ff00
	PushLong #$000f2000
	PushLong #D_StringBuffer
	jsl X_FormatValue
	pla
	PullLong TempPtr
	pla

	lda [TempPtr]
	and #$ff
	inc a
	sta StrSize

	PushLong TempPtr
	PushLong #D_StringBuffer2
	pea 0
	PushWord StrSize
	_BlockMove

	Addwl #11,Sptr

;Here be stuff to manipulate the scrap
cont1	MoveWord FormatLow,X_CurrentFormat
	lda StrSize
	clc
	adc #21
	sta X_CurrentSize
	jsr FixDptr
	jcs awssmemerr

	PushLong #X_CurrentCell
	PushLong Dptr
	PushLong #10
	_BlockMove

	Addwl #10,Dptr

	short
	lda #10
	sta [Dptr]
	long

	IncLong Dptr

	PushLong #D_StringBuffer
	PushLong Dptr
	PushLong #10
	_BlockMove

	Addwl #10,Dptr

	PushLong #D_StringBuffer2
	PushLong Dptr
	pea 0
	pei StrSize
	_BlockMove

	Addwl X_CurrentSize,Doff
	inc Column

	brl cellloop

;*********************************************************************
; label cells

label	lda TypeWord
	and #$20
	jne propogate

	ldx #2
	stz X_CurrentFormat,x

	MoveWord #X_SSCellTypeText,FormatLow

	jsr SetLabelJust

	lda X_StandardProtection
	beq noprotect2

	lda TypeWord
	and #$18
	cmp #$18
	bne noprotect2
	lda X_CurrentFormat+2
	ora #X_SSCellProtect
	sta X_CurrentFormat+2

noprotect2
	lda AWCellSize
	dec a
	sta >D_StringBuffer
	lda Sptr
	clc
	adc #2
	tax
	lda Sptr+2
	adc #0
	pha
	phx
	lda #^D_StringBuffer
	pha
	lda #D_StringBuffer
	inc a
	pha
	pea 0
	lda AWCellSize
	dec a
	pha
	_BlockMove

domovecell
	MoveWord FormatLow,X_CurrentFormat

;bogus size stuff
movecell
	lda >D_StringBuffer
	and #$ff
	inc a
	clc
	adc #11
	sta X_CurrentSize
	jsr FixDptr
	jcs awssmemerr

	PushLong #X_CurrentCell
	PushLong Dptr
	PushLong #10
	_BlockMove

	Addwl #10,Dptr

	short
	lda #0
	sta [Dptr]
	long

	IncLong Dptr

	PushLong #D_StringBuffer
	PushLong Dptr
	pea 0
	lda >D_StringBuffer
	and #$ff
	inc a
	pha
	_BlockMove

	Addwl X_CurrentSize,Doff
	inc AWCellSize
	Addwl AWCellSize,Sptr
	inc Column
	brl cellloop

;*********************************************************************
;propogated label cells

propogate
	MoveLong [CharsHand],ChPtr
	lda Column
	dec a
	asl a
	tay
	lda [ChPtr],y
	sta >D_StringBuffer
	sta StrSize

	ldy #2
	short
	lda [Sptr],y
	sta Char
	ldx #1
pchloop	lda Char
	sta >D_StringBuffer,x
	cpx StrSize
	bge endpchloop
	inx
	bra pchloop

endpchloop
	long
	ldx #2
	stz X_CurrentFormat,x

	MoveWord #X_SSCellTypeText,FormatLow

	lda X_StandardJust
	asl a
	tax
	jmp (FormatTable3,x)

FormatTable3
	DC.W	doprotect3,doprotect3,left3,right3,center3

left3	lda FormatLow
	ora #X_SSCellLeftJustify
	sta FormatLow
	brl doprotect3

center3	lda FormatLow
	ora #X_SSCellCenterJustify
	sta FormatLow
	brl doprotect3

right3	lda FormatLow
	ora #X_SSCellRightJustify
	sta FormatLow

doprotect3
	lda X_StandardProtection
	jeq domovecell

	lda TypeWord
	and #$18
	cmp #$18
	jne domovecell
	lda X_CurrentFormat+2
	ora #X_SSCellProtect
	sta X_CurrentFormat+2
	brl domovecell

endoffile
	MoveLong [Dest],Dptr
	MoveWord MaxBottom,[Dptr]
	MoveWord MaxRight,[Dptr]:#X_SSScrapcols
	MoveWord #1,[Dptr]:#X_SSScrapParseCode
	MoveLong Dsize,[Dptr]:#X_SSScrapSize

;Here we do the messages
	MoveLong [Src],Sptr
	MoveLong [Messhand],Mptr

	MoveWord [Sptr]:#149,[Mptr]:#X_SSMessTop
	MoveWord [Sptr]:#151,a
	and #$ff
	MoveWord a,[Mptr]:#X_SSMessLeft

	MoveWord [Sptr]:#133,[Mptr]:#X_SSMessTopSelect
	MoveWord [Sptr]:#135,a
	and #$ff
	MoveWord a,[Mptr]:#X_SSMessLeftSelect

	MoveWord [Sptr]:#161,a
	sta TitleWord

	and #$80
	bne dotoptitles

	MoveLong #0,[Mptr]:#X_SSMessTopTitles
	bra checkleft

dotoptitles
	MoveWord [Sptr]:#143,[Mptr]:#X_SSMessTopTitles
	MoveWord [Sptr]:#146,[Mptr]:#X_SSMessTopTitles+2

checkleft
	lda TitleWord
	and #$40
	bne dolefttitles

	MoveLong #0,[Mptr]:#X_SSMessLeftTitles
	bra autocalc

dolefttitles
	MoveWord [Sptr]:#145,a
	and #$ff
	MoveWord a,[Mptr]:#X_SSMessLeftTitles
	MoveWord [Sptr]:#148,a
	and #$ff
	MoveWord a,[Mptr]:#X_SSMessLeftTitles+2

autocalc	MoveWord [Sptr]:#132,a
	and #$ff
	cmp #'A'
	bne manual

	MoveWord #1,[Mptr]:#X_SSMessAutoCalc
	bra dozoom

manual	MoveWord #0,[Mptr]:#X_SSMessAutoCalc

dozoom	MoveWord [Sptr]:#240,a
	and #$ff
	MoveWord a,[Mptr]:#X_SSMessFormulas

	stz FormatLow

	lda X_StandardJust
	asl a
	tax
	jmp (DefaultJustTable,x)

DefaultJustTable
	DC.W	error,error,leftd,rightd,centerd

leftd	lda FormatLow
	ora #X_SSCellLeftJustify
	sta FormatLow
	brl enddefaultjust

centerd	lda FormatLow
	ora #X_SSCellCenterJustify
	sta FormatLow
	brl enddefaultjust

rightd	lda FormatLow
	ora #X_SSCellRightJustify
	sta FormatLow

enddefaultjust
	lda X_StandardVForm
	asl a
	tax
	jmp (DefaultTable,x)

DefaultTable
	DC.W	error,error,FixedD,DollarsD,CommasD,PercentD,enddefault

FixedD	lda FormatLow
	ora #X_SSCellFixed
	sta FormatLow
	brl enddefault

DollarsD	lda FormatLow
	ora #X_SSCellDollar
	ora #X_SSCellParenNeg
	sta FormatLow
	brl enddefault

CommasD	lda FormatLow
	ora #X_SSCellComma
	sta FormatLow
	brl enddefault

PercentD	lda FormatLow
	ora #X_SSCellPercent
	sta FormatLow

enddefault
	MoveWord FormatLow,[Mptr]:#X_SSMessFormat
	MoveWord X_StandardDecimals,[Mptr]:#X_SSMessFormat+2

	PushLong CharsHand
	_DisposeHandle

	MoveWord #2,>D_MessageThere

	MoveLong MessHand,>D_Message1

	brl exit


awssmemerr
	PushLong MessHand
	_DisposeHandle
	PushLong CharsHand
	_DisposeHandle
	PushLong Dest
	_DisposeHandle

exit	PushWord X_OldCursor
	jsl D_SetCursor
	return

nullformcell
	MoveWord #0,>D_StringBuffer2
	rts

doformula
	Cmpw AWCellSize,#11
	jeq nullformcell
	MoveLong Sptr,TempPtr
	Addwl AWCellSize,TempPtr
	MoveWord #2,BeginLevel
	MoveWord #$3d01,>D_StringBuffer2

	lda TypeWord
	and #$0800		; check for Calculated Strings
	beq @ValFormula

	ldy #3		; We've got a calculated label
	lda [Sptr],y	;   so get the length of the result
	and #$00ff		;   and add it to "Sptr"
	clc		; Skip the format & length bytes
	adc #4
	Addwl A,Sptr
	bra @LblFormula
	
@ValFormula	Addwl #11,Sptr
@LblFormula	tsc
	sta Stack	 ; D_Save this in case of error

forloop	jsl D_BeachBall
	Cmpl Sptr,TempPtr
	jgt endcellinfo
	lda [Sptr]
	and #$ff
	cmp #X_SSTokenBase
	jlt invalidtoken
continue	sec
	sbc #X_SSTokenBase
	asl a
	tax
	jmp (ParseTable,x)

invalidtoken
	SpaceWord
	PushWord #OKBox
	PushLong #InvalTokenString
	jsl D_AlertBox
	pla

	lda Stack
	tcs
	plx
	MoveWord #-1,err
	brl awssmemerr

InvalTokenString	DC.B	EndInvalString-InvalTokenString-1
	DC.B	'This file has operations that AppleWorks GS'
	DC.B	13
	DC.B	'does not recognize.'
EndInvalString


ParseTable
	DC.W	dofunction	; $C0 @DEG
	DC.W	dofunction	; $C1 @RAD
	DC.W	doNoArgFunc	; $C2 @PI
	DC.W	doNoArgFunc	; $C3 @TRUE
	DC.W	doNoArgFunc	; $C4 @FALSE
	DC.W	dofunction	; $C5 @NOT
	DC.W	dofunction	; $C6 @ISBLANK
	DC.W	dofunction	; $C7 @ISNA
	DC.W	dofunction	; $C8 @ISERROR
	DC.W	dofunction	; $C9 @EXP
	DC.W	dofunction	; $Ca @LN
	DC.W	dofunction	; $Cb @LOG
	DC.W	dofunction	; $Cc @COS
	DC.W	dofunction	; $Cd @SIN
	DC.W	dofunction	; $Ce @TAN
	DC.W	dofunction	; $Cf @ACOS
	DC.W	dofunction	; $D0 @ASIN
	DC.W	doATan2	; $D1 @ATAN2
	DC.W	dofunction	; $D2 @ATAN
	DC.W	dofunction	; $D3 @MOD
	DC.W	doFV	; $D4 @FV
	DC.W	doPV	; $D5 @PV
	DC.W	doPMT	; $D6 @PMT
	DC.W	doTerm	; $D7 @TERM
	DC.W	doRATE	; $D8 @RATE: 	End of 3.0 functions

	DC.W	dofunction	;@Round
	DC.W	dofunction	;@or
	DC.W	dofunction	;@and
	DC.W	dofunction	;@Sum
	DC.W	dofunction	;@Avg
	DC.W	dofunction	;@Choose
	DC.W	dofunction	;@Count
	DC.W	doNoArgFunc	;@Error
	DC.W	doIRR	;@Irr
	DC.W	dofunction	;@if
	DC.W	dofunction	;@Int
	DC.W	dofunction	;@Lookup
	DC.W	dofunction	;@Max
	DC.W	dofunction	;@Min
	DC.W	doNoArgFunc	;@NA
	DC.W	dofunction	;@NPV
	DC.W	dofunction	;@Sqrt
	DC.W	dofunction	;@Abs
	DC.W	dofunction	; really "invalidtoken", but fake function for AW 3.0
	DC.W	dooperator	;<>
	DC.W	dooperator	;>=
	DC.W	dooperator	;<=
	DC.W	dooperator	;=
	DC.W	dooperator	;>
	DC.W	dooperator	;<
	DC.W	docomma	;,
	DC.W	doexp	;^
	DC.W	dorightparen ;)
	DC.W	dooperator	;-
	DC.W	dooperator	;+
	DC.W	dooperator	;/
	DC.W	dooperator	;*
	DC.W	doleftparen	;(
	DC.W	dofunction	;-
	DC.W	dofunction	;+
	DC.W	dofunction	;...
	DC.W	donumber	;
	DC.W	dorow	;
	DC.W	dolitstring	; ""


; transform  @FV (rate, term, pmt [, pv [, type]] ) into 
;	-(FV( pmt, rate, term ) [ *(1 + (NOT(NOT(type)) * rate)) [ + (pv * ((1 + rate) ^ term)) ]] )
;   then let the processor to the rest.
doFV	PushWord	CurLevel	; pretend we've pushed a '(' on stack
	PushWord	BeginLevel

	ldy	#^FVForm
	lda	#FVForm
	bra	do30funct

; transform  @PV (rate, term, pmt [, fv [, type]] ) into 
;	-(PV( pmt, rate, term ) [ *(1 + (NOT(NOT(type)) * rate)) [ + (fv * ((1 + rate) ^ term)) ]] )
;   then let the processor to the rest.

doPV	PushWord	CurLevel	; pretend we've pushed a '(' on stack
	PushWord	BeginLevel

	ldy	#^PVForm
	lda	#PVForm
	bra	do30funct


doPMT	PushWord	CurLevel	; pretend we've pushed a '(' on stack
	PushWord	BeginLevel

	ldy	#^PMTForm
	lda	#PMTForm
	bra	do30funct
	

doTerm	PushWord	CurLevel	; pretend we've pushed a '(' on stack
	PushWord	BeginLevel
	
	ldy	#^TermForm
	lda	#TermForm
	bra	do30funct


; transform @RATE (term, pv, fv ) into RATE( fv, -(pv), term )
;   then let the processor to the rest.

doRATE	ldy	#^RateForm
	lda	#RateForm
	bra	do30funct


; transform @ATAN2(x,y) into @ATAN((y)/(x))
;   then let the processor to the rest.

doATan2	inx		; change it into @ATAN offset
	inx
	ldy	#^ATan2Form
	lda	#ATan2Form
	bra	do30funct


; Transform @IRR( range[, guess] ) to @IRR (guess, range )
;   then let the processor to the rest.
; To do: handle @IRR( range ) to @IRR( .1, range )

doIRR	ldy	#^IRRForm
	lda	#IRRForm
	bra	do30funct


;****************************************************************************

do30funct	
	stx	Func
	sty	Pptr+2
	sta	Pptr

	jsl	getsyshndl	; won't return if error

	jsl	saveallargs

	lda	[Sptr]
	pha

	SubLong	Fptr,#1,Sptr
	AddLong	SystemPtr,#$800,Fptr

	pla
	sta	[Fptr]
	Addwl	#2,Fptr
	MoveWord	#2,Flen

	jsl	buildpat

	Subwl	Flen,Sptr

	Addwls	#$800,SystemPtr
	PushLong	Sptr
	PushWord	#0
	PushWord	Flen
	_BlockMove

	jsl	freesyshndl
	ldx	Func


; do30funct falls through to dofunctions


dofunction
	txa
	asl a
	asl a
	clc
	adc #4
	tax

	PushLong #D_StringBuffer2
	PushLong X_AWFormulaTable:x
	PushLong #D_StringBuffer2
	jsl D_AddStrings

	IncLong Sptr
	brl forloop

doNoArgFunc Addwl #3,Sptr	; skip 3 null bytes following no arguments functions
	brl dofunction

;doerror3bytes
;	phx
;	Addwl #3,Sptr
;	plx
;	brl dofunction

;doNA	Addwl #3,Sptr
;	brl dofunction

dooperator
	pha
	lda CurLevel
	cmp #-1
	bne doparens
	lda 1,s
	asl a
	asl a
	inc a
	inc a
	tax
	lda X_AWFormulaTable,x
	sta CurLevel
	plx
	brl dofunction

doparens	lda 1,s
	asl a
	asl a
	inc a
	inc a
	tax
	lda X_AWFormulaTable,x
	cmp CurLevel
	bgt nodoformula
	sta CurLevel
	plx
	brl dofunction

nodoformula
	sta CurLevel
	lda #D_StringBuffer2
	clc
	adc BeginLevel
	tax
	lda #^D_StringBuffer2
	adc #0
	pha
	phx
	lda 1,s
	inc a
	tax
	lda 3,s
	pha
	phx
	lda >D_StringBuffer2
	and #$ff
	sec
	sbc BeginLevel
	inc a
	pea 0
	pha
	_BlockMove

	short
	ldx BeginLevel
	lda #$28
	sta >D_StringBuffer2,x
	lda >D_StringBuffer2
	inc a
	sta >D_StringBuffer2
	tax
	inx
	lda #$29
	sta >D_StringBuffer2,x
	lda >D_StringBuffer2
	inc a
	sta >D_StringBuffer2
	long
	plx
	brl dofunction

docomma	lda >D_StringBuffer2
	and #$ff
	inc a
	inc a
	sta BeginLevel
	MoveWord #-1,CurLevel
	brl dofunction

doexp	pha
	lda CurLevel
	cmp #-1
	bne insert
	MoveWord #8,CurLevel
	plx
	brl dofunction
insert	lda #8
	brl nodoformula

dorightparen
	PullWord BeginLevel
	PullWord CurLevel
	brl dofunction

doleftparen
	PushWord CurLevel
	PushWord BeginLevel
	brl docomma

donumber	IncLong Sptr

	PushLong Sptr
	PushLong #X_NumberStr
	FD2X

	SpaceWord
	SpaceLong
	SpaceWord
	PushWord #$ff00
	PushLong #$00f2000
	PushLong #X_NumberStr
	jsl X_FormatValue
	pla
	PullLong X_NumberStr
	pla

	PushLong #D_StringBuffer2
	PushLong X_NumberStr
	PushLong #D_StringBuffer2
	jsl D_AddStrings

	Addwl #8,Sptr
	brl forloop

dorow	IncLong Sptr
	lda #0

	short
	lda [Sptr]
	clc
	adc Column
	long
	pha
	jsr Int2Column
	bcs single
	lda #2
	bra cont7
single	lda #1
cont7	sta X_NumberStr
	pla
	sta X_NumberStr+1
	IncLong Sptr
	lda [Sptr]
	clc
	adc row
	pha
	PushLong #RowStr+1
	lda 5,s

	cmp #10
	bge notone
	lda #1
	bra dopush
	
notone	cmp #100
	bge nottwo
	lda #2
	bra dopush
	
nottwo	cmp #1000
	bge notthree
	lda #3
	bra dopush

notthree	lda #4

dopush	sta >RowStr

	pha
	PushWord #0
	_Int2Dec

	PushLong #X_NumberStr
	PushLong #RowStr
	PushLong #X_NumberStr
	jsl D_AddStrings

	PushLong #D_StringBuffer2
	PushLong #X_NumberStr
	PushLong #D_StringBuffer2
	jsl D_AddStrings

	Addwl #2,Sptr
	brl forloop

RowStr	DS.B 5

endcellinfo
	lda >D_StringBuffer2
	and #$ff
	inc a
	rts

dolitstring	IncLong Sptr	; get past the token	

	PushLong #D_StringBuffer2
	PushLong #quoteStr
	PushLong #D_StringBuffer2
	jsl D_AddStrings

	PushLong #D_StringBuffer2
	PushLong Sptr
	PushLong #D_StringBuffer2
	jsl D_AddStrings

	PushLong #D_StringBuffer2
	PushLong #quoteStr
	PushLong #D_StringBuffer2
	jsl D_AddStrings

	lda [Sptr]		; get the length
	and #$00ff		; Move past the string
	inc a		;   including the length byte
	Addwl A,Sptr
	brl forloop		; and return

quoteStr	str '"'

;****************************************************************************

SetLabelJust lda TypeWord
	and #%111
	asl a
	tax
	jmp (JustTable1,x)

JustTable1
	DC.W	standard1,standard1,left1,right1,center1
	DC.W	standard1,center1,standard1

standard1
	lda X_StandardJust
	asl a
	tax
	jmp (JustTable1,x)

left1	lda FormatLow
	ora #X_SSCellLeftJustify
	sta FormatLow
	brl endjust1

center1	lda FormatLow
	ora #X_SSCellCenterJustify
	sta FormatLow
	brl endjust1

right1	lda FormatLow
	ora #X_SSCellRightJustify
	sta FormatLow

endjust1	rts

;****************************************************************************

arglength	ldy	#0
arglength1	stz	Parens

arglenloop	lda	[Fptr],y
	and	#$00ff
	cmp	#X_SSAWLParen
	bne	arglen1

	inc	Parens
	bra	arglennxt

arglen1	cmp	#X_SSAWRParen
	bne	arglen2

	lda	Parens
	beq	arglenend

	dec	Parens
	bra	arglennxt

arglen2	cmp	#X_SSAWRowCol
	bne	arglen3

	tya
	clc
	adc	#4
	tay
	bra	arglenloop	

arglen3	cmp	#X_SSAWNumber
	bne	arglen4

	tya
	clc
	adc	#9
	tay
	bra	arglenloop	

arglen4	cmp	#X_SSAWString
	bne	arglen5

	lda	[Fptr],y
	xba
	and	#$00ff
	sta	Alen
	tya
	clc
	adc	#2	; for token & length bytes
	addword	a,Alen,a
	tay
	bra	arglenloop

arglen5	ldx	Parens
	bne	arglennxt

	cmp	#X_SSAWComma
	bne	arglennxt

	clc
	bcc	arglenout

arglennxt	iny
	bra	arglenloop

arglenend	sec
arglenout	rtl

;****************************************************************************

svarglen	asl	a
	tay
	lda	[SystemPtr],y
	rtl


;****************************************************************************

saveallargs	
	stz	Acnt
	AddLong	Sptr,#2,Fptr
	AddLong	SystemPtr,#$100,Aptr

saaloop	jsl	arglength
	php		; save status

	inc	Acnt	; one more arg

	tya		; save argument's length
	tax
	stx	Alen
	stz	Alen+2
	lda	Acnt
	asl	a
	tay
	txa
	sta	[SystemPtr],y

; now save the argument to the SystemHandle space

	tool	_BlockMove,in=(Fptr:l,Aptr:l,Alen:l)

	lda	Alen
	inc	a	; skip comma
	Addwl	a,Fptr	; increment the Functions's pointer

	plp		; restore status
	bcs	saaout	; carry set = last argument

	Addwl	#$100,Aptr	; get ready for the next argument

	bra	saaloop	; get the next arg
	
saaout	rtl

;****************************************************************************

movearg#	pha		; a = argument number
	asl	a	; get argument's length
	tay
	lda	[SystemPtr],y
	sta	Alen
	stz	Alen+2

	MoveLong	SystemPtr,Aptr

	pla		; restore arg #, and convert to offset
	xba
	Addwl	a,Aptr

; move arg from SystemHandle space to Fptr

	tool	_BlockMove,in=(Aptr:l,Fptr:l,Alen:l)

	Addwl	Alen,Fptr
	Addwl	Alen,Flen

	rtl

	
;****************************************************************************

getsyshndl	jsl	D_CheckPurge
	bcs	nosyshndl

	lda	>D_SystemHandle+2
	tax
	lda	>D_SystemHandle
	rcall	D_Deref,out=(SystemPtr:ax)

	rtl

nosyshndl	SpaceWord
	PushWord #OKBox
	PushLong #MemoryErrMsg
	jsl D_AlertBox
	pla

	lda Stack
	tcs
	plx
	MoveWord #-1,err
	brl awssmemerr


MemoryErrMsg	str	'Out of System Memory.'

;****************************************************************************

freesyshndl
	tool _HUnlock,in=(>D_SystemHandle:l)
	rtl

;****************************************************************************

X_SSAWNot	 equ	$C5
X_SSAWExp	 equ	$F3
X_SSAWMinus	 equ	$F5
X_SSAWPlus	 equ	$F6
X_SSAWDivide equ	$F7
X_SSAWTimes	 equ	$F8
X_SSAWUMinus equ	$FA
X_SSAWNper	 equ	$EB	; This function does not really exist in AW 3.0
			; in other words, this is a hack solution
			; that may need to be changed if this token
			; ever gets used in a future (he he) version of AW.
AWSS_End	equ	$00
AWSS_Arg1	equ	$01
AWSS_Arg2	equ	$02
AWSS_Arg3	equ	$03
AWSS_Arg4	equ	$04
AWSS_Arg5	equ	$05
AWSS_Form	equ	$06
AWSS_One	equ	$07
AWSS_Number	equ	$08
AWSS_Byte	equ	$09
AWSS_IfAcnt	equ	$0a

;****************************************************************************************************
; The following form's are used for translating AW 3.0's financial functions.
; These functions often have additional, optional arguments, and also arguments
; in a different order than AWGS.
;
; The pattern's consist of a series of AppleWorks tokens and several special
; purpose tokens:
;
;	AWSS_Arg#	tspecifies the argument (1-5) that should be placed at 
;		this possition.
;	AWSS_One	Move the numeric constant one (1) into formula
;	AWSS_Number	(unused/unimpimented) the next long word is the address of an
;		AW double format SANE number to be placed in the formula
;	AWSS_Form	the next long word is the address of another form (forms
;		can be nested, you see)
;	AWSS_Byte	(unused/commented out)the next token should be placed into
;		the token string carefully (i.e., put only that one byte) 
;		so that it doesn't overwrite part of the file
;	AWSS_IfAcnt	do the next item (which is an AWSS_Form), if Acnt = byte
;
; All forms must end with a NULL word: two bytes of zero.
;****************************************************************************

FVForm	dc.b	AWSS_Form
	dc.l	FVPVForm
	dc.b	AWSS_IfAcnt,4,AWSS_Form
	dc.l	Form_fvpv
	dc.w	AWSS_End

PVForm	dc.b	AWSS_Form
	dc.l	FVPVForm
	dc.b	AWSS_IfAcnt,4,AWSS_Form
	dc.l	Form_pvfv
	dc.w	AWSS_End
	
FVPVForm	dc.b	AWSS_Arg3,X_SSAWComma,AWSS_Arg1,X_SSAWComma,AWSS_Arg2,X_SSAWRParen
	dc.b	AWSS_IfAcnt,5,AWSS_Form
	dc.l	Form_type
	dc.w	AWSS_End

Form_pvfv	dc.b	AWSS_Form
	dc.l	PVFV_w_fvpv
	dc.b	X_SSAWUMinus,AWSS_Arg2,X_SSAWRParen,X_SSAWRParen
	dc.w	AWSS_End

Form_fvpv	dc.b	AWSS_Form
	dc.l	PVFV_w_fvpv
	dc.b	AWSS_Arg2,X_SSAWRParen,X_SSAWRParen
	dc.w	AWSS_End

;+ (pv * ((rate + 1) ^ term))
PVFV_w_fvpv	dc.b	X_SSAWPlus,X_SSAWLParen,AWSS_Arg4,X_SSAWTimes,X_SSAWLParen,X_SSAWLParen
	dc.b	AWSS_Arg1,X_SSAWPlus,AWSS_One,X_SSAWRParen,X_SSAWExp
	dc.w	AWSS_End

;****************************************************************************

; pv, rate, term
PMTForm	dc.b	AWSS_IFAcnt,4,AWSS_Form
	dc.l	PMTForm_fv
	dc.b	AWSS_Arg3,X_SSAWComma,AWSS_Arg1,X_SSAWComma,AWSS_Arg2
	dc.b	X_SSAWRParen,AWSS_IfAcnt,5,AWSS_Form
	dc.l	PMTForm_type
	dc.w	AWSS_End

;  fv * ((rate + 1)^-term) + pv, rate, term) 
PMTForm_fv	dc.b	AWSS_Arg4,X_SSAWTimes,X_SSAWLParen,X_SSAWLParen,AWSS_Arg1
	dc.b	X_SSAWPlus,AWSS_One,X_SSAWRParen,X_SSAWExp,X_SSAWUMinus
	dc.b	AWSS_Arg2,X_SSAWRParen,X_SSAWPlus
	dc.w	AWSS_End

; * ( rate * NOT(NOT(type)) + 1 )
Form_type	dc.b	X_SSAWTimes,AWSS_Form
	dc.l	Type_Fudge
	dc.w	AWSS_End

; / (NOT(NOT(type)) * rate + 1)
PMTForm_type dc.b	X_SSAWDivide,AWSS_Form
	dc.l	Type_Fudge
	dc.w	AWSS_End

Type_Fudge	dc.b	X_SSAWLParen,X_SSAWNot,X_SSAWLParen,X_SSAWNot,X_SSAWLParen
	dc.b	AWSS_Arg5,X_SSAWRParen,X_SSAWRParen,X_SSAWTimes
	dc.b	AWSS_Arg1,X_SSAWPlus,AWSS_One
	dc.b	X_SSAWRParen
	dc.w	AWSS_End

;****************************************************************************

; [ (-term( ] pmt Form_type,rate,pv)  [ ) ]
TermForm	dc.b	AWSS_Arg2,AWSS_IfAcnt,5,AWSS_Form
	dc.l	Form_type
	dc.b	X_SSAWComma,AWSS_Arg1,X_SSAWComma,AWSS_Arg3,X_SSAWRParen
	dc.b	AWSS_IfAcnt,4,AWSS_Form
	dc.l	TermForm_fv
	dc.w	AWSS_End

; + term<"nper">(pmt Form_type, rate, -(fv))
TermForm_fv	dc.b	X_SSAWPlus,X_SSAWNper,X_SSAWLParen,AWSS_Arg2,AWSS_IfAcnt,5,AWSS_Form
	dc.l	Form_type
	dc.b	X_SSAWComma,AWSS_Arg1,X_SSAWComma,X_SSAWUMinus,X_SSAWLParen
	dc.b	AWSS_Arg4,X_SSAWRParen,X_SSAWRParen
	dc.w	AWSS_End

;****************************************************************************

Atan2Form	dc.b	X_SSAWLParen,AWSS_Arg2,X_SSAWRParen,X_SSAWDivide
	dc.b	X_SSAWLParen,AWSS_Arg1,X_SSAWRParen
	dc.w	AWSS_End

IRRForm	dc.b	AWSS_Arg2,X_SSAWComma,AWSS_Arg1
	dc.w	AWSS_End

RateForm	dc.b	AWSS_Arg3,X_SSAWComma,X_SSAWUMinus,X_SSAWLParen,AWSS_Arg2,X_SSAWRParen
	dc.b	X_SSAWComma,AWSS_Arg1
	dc.w	AWSS_End

DblOne	dc.b	X_SSAWNumber
	dc.d	"1.0"	; for financial function formulas


;****************************************************************************************************
; buildpat	takes a pointer to the one of the above tables, and creating the appropriate AW formula
;	tokens in the SystemHandle data space and keeping a count of the tokens created in the
;	DP variable Flen.  These formula tokens can then be inserted into the data stream for
;	the regular parser to translate.  It processes this form by scanning byte by byte, 
;	executing special actions if the byte is a control byte.
;
;	saveallargs should be called before calling buildpat.  It will save the function's 
;	arguments and their sizes to the SystemHandle, and set Acnt to the # of arguments.
;
;	INPUT:	a pointer to a form stored in the DP variable Pptr
;
;	OUTPUT:	Flen (count of tokens to be inserted in data stream)
; 
; see the header comment above the forms for a description of the control bytes used in buildpat
;****************************************************************************************************

buildpat	stz	Pndx

bploop	ldy	Pndx
	lda	[Pptr],y	; get data from form
	jeq	bpdone

	and	#$00ff	 ; just care about low byte
	cmp	#AWSS_Arg5+1 ; If it's 1-5, it's an argument #
	bcs	bp1

;	we moving an argument
	jsl	movearg#	; now move the argument into place

	inc	Pndx
	bra	bploop

bp1	cmp	#AWSS_One
	bne	bp2

;	we are moving the number one in AW SANE format

	tool	_BlockMove,in=(#DblOne:l,Fptr:l,#9:l)

	inc	Pndx
	Addwl	#9,Fptr
	AddWord	Flen,#9,Flen

	bra	bploop

bp2
;	cmp	#AWSS_Byte
;	bne	bp3
;
;	we are moving just a byte
;	so be careful about inserting it
;
;	inc	Pndx
;	iny
;	lda	[Fptr]	; get a token from the stream
;	and	#$ff00
;	ora	[Pptr],y	; combine it with new token
;	bra	bpstore	;   the token must be followed by a zero
;
bp3	cmp	#AWSS_Form
	bne	bp4

;	it's a new form!!

	PushLong	Pptr	; Save the current index and form address
	PushWord	Pndx

	iny		; move the new form address to direct pg
	lda	[Pptr],y
	tax
	iny
	iny
	lda	[Pptr],y
	sta	Pptr+2
	stx	Pptr

	jsl	buildpat	; restore the patern

	PullWord	Pndx	; restore the index & form address
	PullLong	Pptr

	AddWord	Pndx,#5,Pndx
	brl	bploop

bp4	cmp	#AWSS_IfAcnt
	bne	bp5

;	it's the dreaded IfAcnt, check how many arguments were given
;	if it's greater or equal, do the next form

	iny
	AddWord	Pndx,#2,Pndx
	lda	Acnt

	shortm
	cmp	[Pptr],y
	longm
	jge	bploop

	AddWord	Pndx,#5,Pndx
	brl	bploop

;	just a AW token

bp5
bpstore	sta	[Fptr]

	inclong	Fptr
	inc	Pndx
	inc	Flen
	brl	bploop
	
bpdone	rtl

;****************************************************************************************************

Int2Column
	lda 3,s
	cmp #27
	jge dotwodigit
	clc
	adc #$40
	sta 3,s
	sec
	rts

dotwodigit
	ldy #0
	lda 3,s
loops	sec
	sbc #26
	beq foundupper
	bmi foundupper
	iny
	bra loops
foundupper
	clc
	adc #26
	tax
	tya
	clc
	adc #$40
	xba
	pha
	txa
	clc
	adc #$40
	ora 1,s
	xba
	sta 5,s
	pla
	clc
	rts

FixDptr	clc
	adc Dsize
	sta Dsize
	bcc x2
	inc Dsize+2
x2	pei Dsize+2
	pei Dsize
	pei Dest+2
	pei Dest
	jsl D_GrowHandle
	sta err
	bcc noprob
	rts
noprob	MoveLong [Dest],RealDptr
	AddLong RealDptr,Doff,Dptr
	clc
	rts


	ENDP
	END

