
		LOAD		'Macros.dump'
		INCLUDE	'M16.Profile'

		INCLUDE	'SS.equ'

		INCLUDE	'Driver.equ'
		INCLUDE	'Heap.aii.i'
		INCLUDE	'Eval.aii.i'

;-----------------------------------------------
;
;	Imported addresses
;
;-----------------------------------------------

		IMPORT	S_AddCellToChangedList
		IMPORT	S_AddCellToDepList
		IMPORT	S_CellWidth
		IMPORT	S_CurBRMost
		IMPORT	S_CurDefFormat
		IMPORT	S_CurEditFlag
		IMPORT	S_DepOnMeTreeTooBig
		IMPORT	S_FindLeftContent
		IMPORT	S_FindRightContent
		IMPORT	S_GetCellIndex
		IMPORT	S_GetCellPtr
		IMPORT	S_GetCellTableEntry
		IMPORT	S_GetRealCell
		IMPORT	S_LoadingFile
		IMPORT	S_NormalizeRange
		IMPORT	S_RemoveCellFromChangedList
		IMPORT	S_RemoveCellFromDepList
		IMPORT	S_ResetCircularBits
		IMPORT	S_SetCellTableEntry
		IMPORT	S_TraverseDependOnMeTree
		IMPORT	S_TraverseRange

;-----------------------------------------------
;
;	Forward addresses and entries
;
;-----------------------------------------------

		ENTRY	S_DependHomeCell
		ENTRY	S_EnterRangeDep
		ENTRY	S_GetCellPriority
		ENTRY	S_InsertLeftPadCells
		ENTRY	S_RemoveCell
		ENTRY	S_RemoveDependency
		ENTRY	S_RemoveRangeDep
		ENTRY	S_UpdateCellPriority

;----------------------------------------------------------------------------
;	S_NewCell

S_NewCell		PROC		EXPORT
			;Using	S_CurrentData

			input	Cell:l,CellType:w,Format:l,Content:l
			output	Index:l,CellPtr:l
			local	DepOnMe:l
			error	ErrorFlag
			BEGIN

			stz		ErrorFlag

			in		Cell:l
			out		Index:l
			XCall	S_GetCellTableEntry

			ora		Index
			beq		noOldCell

			lda		Index+2
			and		#S_CellTableFlags
			bne		noOldCell

			H_GetBlockPtr	Index,CellPtr

			brl		gotCellPtr

noOldCell
			MoveLong	Index,DepOnMe

			H_NewBlock	#S_CellStructSize,Index,err=ErrorFlag
			jcs			Exit

;	Set Index for Cell	;

			in		Cell:l,Index:l
			XCall	S_SetCellTableEntry,err=ErrorFlag
			bcc		doOK

			H_DisposeBlock	Index
			brl			Exit

	;	Set up New Cell structure	;

doOK
			H_GetBlockPtr	Index,CellPtr

			lda		#0
			MoveWord	a,[CellPtr]:#S_CellNext
			MoveWord	a,[CellPtr]:#S_CellNext+2
			MoveWord	a,[CellPtr]:#S_CellPrevious
			MoveWord	a,[CellPtr]:#S_CellPrevious+2

			MoveWord	a,[CellPtr]:#S_CellPriority

			MoveLong	Cell,[CellPtr]:#S_CellID
			MoveLong	DepOnMe,[CellPtr]:#S_CellDependOnMe

gotCellPtr
			lda		Format
			and		#$FFFF-S_CellType
			ora		CellType
			MoveWord	a,[CellPtr]:#S_CellFormat
			MoveWord	Format+2,[CellPtr]:#S_CellFormat+2

			MoveLong	Content,[CellPtr]:#S_CellContent

			lda		#0
			ldy		#S_CellValue+8
loop
			sta		[CellPtr],y
			dey
			dey
			cpy		#S_CellValue
			bge		loop

			lda		CellType
			bmi		Exit

			lda		S_CurEditFlag
			and		#S_BRMostBit
			bne		Exit

			CmpWord	S_CurBRMost,Cell
			bge		chkRight

			MoveWord	Cell,S_CurBRMost

chkRight
			CmpWord	S_CurBRMost+2,Cell+2
			bge		Exit

			MoveWord	Cell+2,S_CurBRMost+2

Exit
			RETURN
			ENDP

;----------------------------------------------------------------------------
;	S_UpdatePriorities
;

S_UpdatePriorities	PROC		EXPORT
				;Using	S_CurrentData
				;Using	S_PriorityData

			input	Cell:l
			BEGIN

			in		Cell:l,#S_UpdateCellPriority:l
			XCall	S_TraverseDependOnMeTree

			RETURN
			ENDP

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

S_PriorityData	PROC		EXPORT

			EXPORT	S_MaxPriority

S_MaxPriority	DS.B		2

			ENDP

;----------------------------------------------------------------------------
;	S_UpdateCellPriority
;

S_UpdateCellPriority	PROC		EXPORT

			input	CellPtr:l
			output	ProceedCode:w
			local	Cell:l,ContentPtr:l
			local	NumCells:w,CurCell:w,DepCellPtr:l
			local	DepListPtr:l,LastPtr:l,DependList:l
			local	RefType:w,TargetCell:l,TargetCell2:l
			error	AbortFlag
			BEGIN

			stz		AbortFlag

			MoveLong	[CellPtr]:#S_CellID,Cell

			MoveWord	[CellPtr]:#S_CellFormat+2,a
			and		#S_CellCircular
			jne		dontProceed

			stz		S_MaxPriority

			MoveWord	[CellPtr]:#S_CellFormat,a
			jmi		gotPriority

			and		#S_CellTypeTextForm				; any formula
			jeq		gotPriority

	;	The cell is of type formula, although we don't car which kind

			H_GetBlockPtr	[CellPtr]:#S_CellContent,ContentPtr

			MoveWord	[ContentPtr]:#E_FormulaCells,NumCells
			MoveWord	#E_FormulaData,CurCell
			cmp		NumCells
			jge		gotPriority

loop
			MoveWord	[ContentPtr]:CurCell,a
			and		#$00FF
			sta		RefType

			iny
			in		[ContentPtr]:y:l,RefType:w,Cell:l
			out		TargetCell:l
			XCall	S_GetRealCell

			lda		RefType
			and		#$0080
			beq		singCell

			AddWord	CurCell,#5,CurCell

			tay
			MoveWord	[ContentPtr]:y,a
			and		#$00FF
			sta		RefType

			iny
			in		[ContentPtr]:y:l,RefType:w,Cell:l
			out		TargetCell2:l
			XCall	S_GetRealCell

			Call		S_NormalizeRange,in=(TargetCell:l,TargetCell2:l)

			in		#S_GetCellPriority:l	; 2 inputs on stack
			XCall	S_TraverseRange

			bra		prioritySet

singCell
			Call		S_GetCellPriority,in=(TargetCell:l)

prioritySet
			AddWord	CurCell,#5,CurCell
			cmp		NumCells
			jlt		loop

gotPriority
			CmpWord	S_MaxPriority,[CellPtr]:#S_CellPriority
			beq		dontProceed

			sta		[CellPtr],y
			stz		ProceedCode
			bra		Exit

dontProceed
			MoveWord	#1,ProceedCode

Exit
			RETURN
			ENDP

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

S_GetCellPriority	PROC		EXPORT
				;Using	S_PriorityData

			input	Cell:l
			local	CellPtr:l
			BEGIN

			in		Cell:l
			out		CellPtr:l
			XCall	S_GetCellPtr

			ora		CellPtr
			beq		emptyCell

			MoveWord	[CellPtr]:#S_CellPriority,a
			bra		adjustPriority

emptyCell
			lda		#0

adjustPriority
			inc		a
			cmp		S_MaxPriority
			blt		Exit

			sta		S_MaxPriority

Exit
			RETURN
			ENDP

;-----------------------------------------------------------------------------
;	S_RemovePadCells( Cell:l )
;

S_RemovePadCells	PROC		EXPORT
				;Using	S_CurrentData

			input	Cell:l
			output	LCell:l,RCell:l
			local	CellPtr:l,Format:l
			error	ErrFlag
			BEGIN

			stz		ErrFlag

			MoveWord	Cell,LCell
			sta		RCell

			MoveWord	Cell+2,LCell+2
			sta		RCell+2

;			in		Cell:l			; Dont check, so we can remove
;			out		CellPtr:l			; those on one side of a given
;			XCall	S_GetCellPtr		; column during resize columns
;
;			ora		CellPtr
;			jeq		Exit

	;	Remove those on the left first	;

lfloop
			dec		Cell+2
			beq		lfdone

			in		Cell:l
			out		CellPtr:l
			XCall	S_GetCellPtr

			ora		CellPtr
			beq		lfdone

			MoveLong	[CellPtr]:#S_CellFormat,Format
;			bpl		lfdone

			lda		Format
			and		#S_CellType
			cmp		#S_CellTypeLeftPad
			bne		lfdone

			Call		S_RemoveCell,in=(Cell:l)

			MoveWord	Cell+2,LCell+2
			bra		lfloop
lfdone

	;	Remove those on the right	;

			MoveWord	RCell+2,Cell+2

rtloop
			inc		Cell+2
			CmpWord	Cell+2,#$02BF
			jge		Exit					; no pad cells to insert

			in		Cell:l
			out		CellPtr:l
			XCall	S_GetCellPtr

			ora		CellPtr
			jeq		Exit					; no pad cells to insert

			MoveLong	[CellPtr]:#S_CellFormat,Format

			lda		Format
			and		#S_CellType
;			bpl		insertPadCells

			cmp		#S_CellTypeRightPad
			bne		insertPadCells

			Call		S_RemoveCell,in=(Cell:l)

			MoveWord	Cell+2,RCell+2
			bra		rtloop

	;	Add left pad cells to existing cells, if necessary	;

insertPadCells

			cmp		#S_CellTypeText
			beq		doIt

			cmp		#S_CellTypeLeftPad
			bne		Exit

;			inc		Cell+2

;			in		Cell:l
;			out		Cell:l,a:w
;			XCall	S_FindRightContent

doIt
			Call		S_InsertLeftPadCells,in=(Cell:l),out=(:l),err=ErrFlag

			pla
			pla
			cmp		LCell+2
			bge		Exit

			sta		LCell+2

Exit
			RETURN
			ENDP

;-----------------------------------------------------------------------------
;	S_InsertRightPadCells( Cell:l ): RCell:l
;

S_InsertRightPadCells	PROC		EXPORT
					;Using	S_CurrentData

			input	Cell:l
			output	RCell:l
			local	CellStrPtr:l,StringWd:w,TotalWd:w
			local	OrigCellPtr:l,NewCellPtr:l,Format:l
			local	NewCellIndex:l,Justify:w
			error	ErrFlag
			BEGIN

	ProfileIn		11

			stz		ErrFlag

	;	Initialize Output	;

			MoveLong	Cell,RCell

			in		Cell:l
			out		OrigCellPtr:l
			XCall	S_GetCellPtr

			ora		OrigCellPtr
			jeq		Exit

	;	Cell structure exists	;

			MoveLong	[OrigCellPtr]:#S_CellFormat,Format

			lda		Format
			and		#S_CellType
			cmp		#S_CellTypeRightPad

			bne		gotContent

	;	Get the Content Cell	;

			in		Cell:l
			out		Cell:l,a:w
			XCall	S_FindLeftContent

			in		Cell:l
			out		OrigCellPtr:l
			XCall	S_GetCellPtr

			MoveLong	[OrigCellPtr]:#S_CellFormat,Format

	;	Cell has contents	;

gotContent
			lda		Format
			and		#S_CellType
			cmp		#S_CellTypeText
			jne		Exit

			lda		Format
			and		#S_CellJustify
			cmp		#S_CellRightJustify
			jeq		Exit

	;	Right pad cells may be needed	;

			sta		Justify

	;	Get the String width	;

			Tool		_GetTextFace,out=(:w)		; leave on stack

			lda		Format
			and		#S_CellBold
			beq		textFaceSet

			lda		1,s
			ora		#$01						; set bold bit on
			Tool		_SetTextFace,in=(a:w)

textFaceSet
			H_GetBlockPtr	[OrigCellPtr]:#S_CellContent,CellStrPtr

			Tool		_StringWidth,in=(CellStrPtr:l),out=(StringWd:w)

			Tool		_SetTextFace,in=(:w)		; input from _GetTextFace


	;	Get enough cells to fit string, if possible	;

			MoveWord	#S_MagNum1,TotalWd

			lda		Justify
			jeq		rtchk

			Call		S_CellWidth,in=(Cell+2:w),out=(a:w)

			AddWord	a,#S_MagNum1,a
			AddWord	a,StringWd,a
			lsr		a
			sta		StringWd

			brl		rtchk

rtloop
			inc		Cell+2
			CmpWord	Cell+2,#$02BF
			jge		rtdone

			in		Cell:l
			out		NewCellPtr:l
			XCall	S_GetCellPtr

			ora		NewCellPtr
			beq		rtcont

	;	Check to see if it is a pad cell, ...	;

			MoveLong	[NewCellPtr]:#S_CellFormat,Format

			lda		Format
			bpl		rtdone

			and		#S_CellType
			cmp		#S_CellTypeRightPad
			beq		rtchk

	;	Change the direction of the overlap.	;

			lda		Format
			and		#$FFFF-S_CellType
			ora		#S_CellTypeRightPad
			MoveWord	a,[NewCellPtr]:#S_CellFormat

			bra		rtOK

rtcont
			in		Cell:l,#S_CellTypeRightPad:w,S_CurDefFormat:l,#0:l
			out		NewCellIndex:l,NewCellPtr:l
			XCall	S_NewCell,err=ErrFlag
			bcs		rtdone

rtOK
			MoveWord	Cell+2,RCell+2

rtchk
			Call		S_CellWidth,in=(Cell+2:w),out=(a:w)
			AddWord	a,TotalWd,TotalWd
			cmp		StringWd
			jlt		rtloop
rtdone

Exit

	ProfileOut	11

			RETURN
			ENDP

;-----------------------------------------------------------------------------
;	S_InsertLeftPadCells( Cell:l ): LCell:l
;

S_InsertLeftPadCells	PROC		EXPORT
					;Using	S_CurrentData

			input	Cell:l
			output	LCell:l
			local	CellStrPtr:l,StringWd:w,TotalWd:w
			local	OrigCellPtr:l,NewCellPtr:l,Format:l
			local	NewCellIndex:l,Justify:w
			error	ErrFlag
			BEGIN

	ProfileIn		12

			stz		ErrFlag

	;	Initialize output	;

			MoveLong	Cell,LCell

			in		Cell:l
			out		OrigCellPtr:l
			XCall	S_GetCellPtr

			ora		OrigCellPtr
			jeq		Exit

	;	Cell structure exists	;

			MoveLong	[OrigCellPtr]:#S_CellFormat,Format

			lda		Format
			and		#S_CellType
			cmp		#S_CellTypeLeftPad

			bne		gotContent

	;	Get the Content Cell, we are adding to the left end of some	;
	;	left pad cells										;

			in		Cell:l
			out		Cell:l,a:w
			XCall	S_FindRightContent

			in		Cell:l
			out		OrigCellPtr:l
			XCall	S_GetCellPtr

			MoveLong	[OrigCellPtr]:#S_CellFormat,Format

	;	Cell has contents	;

gotContent
			lda		Format
			and		#S_CellType
			cmp		#S_CellTypeText
			jne		Exit

			lda		Format
			and		#S_CellJustify
;			cmp		#S_CellLeftJustify			; = 0
			jeq		Exit

	;	Left pad cells may be needed	;

			sta		Justify

	;	Get the String width	;

			Tool		_GetTextFace,out=(:w)		; leave on stack

			lda		Format
			and		#S_CellBold
			beq		textFaceSet

			lda		1,s
			ora		#$01						; set bold bit on
			Tool		_SetTextFace,in=(a:w)

textFaceSet
			H_GetBlockPtr	[OrigCellPtr]:#S_CellContent,CellStrPtr

			Tool		_StringWidth,in=(CellStrPtr:l),out=(StringWd:w)

			Tool		_SetTextFace,in=(:w)		; input from _GetTextFace


	;	Get enough cells to fit string, if possible	;

			MoveWord	#S_MagNum1,TotalWd

			lda		Justify
			cmp		#S_CellRightJustify
			jeq		lfchk

			Call		S_CellWidth,in=(Cell+2:w),out=(a:w)
			AddWord	a,#S_MagNum1,a
			AddWord	a,StringWd,a
			lsr		a
			sta		StringWd

			brl		lfchk

lfloop
			dec		Cell+2
			jeq		lfdone

			in		Cell:l
			out		NewCellPtr:l
			XCall	S_GetCellPtr

			ora		NewCellPtr
			beq		lfcont

	;	Check to see if it is a pad cell, ...	;

			MoveLong	[NewCellPtr]:#S_CellFormat,Format

			lda		Format
			bpl		lfDone

			and		#S_CellType
			cmp		#S_CellTypeLeftPad
			beq		lfchk

			cmp		#S_CellTypeRightPad
			beq		lfDone

			lda		Format
			and		#$FFFF-S_CellType
			ora		#S_CellTypeLeftPad
			MoveWord	a,[NewCellPtr]:#S_CellFormat

			bra		lfOK

lfcont
			in		Cell:l,#S_CellTypeLeftPad:w,S_CurDefFormat:l,#0:l
			out		NewCellIndex:l,NewCellPtr:l
			XCall	S_NewCell,err=ErrFlag
			bcs		lfDone

lfOK
			MoveWord	Cell+2,LCell+2

lfchk
			Call		S_CellWidth,in=(Cell+2:w),out=(a:w)
			AddWord	a,TotalWd,TotalWd
			cmp		StringWd
			jlt		lfloop
lfDone

Exit

	ProfileOut	12

			RETURN
			ENDP

;----------------------------------------------------------------------------
;	S_RemoveCell( Cell:l )
;

S_RemoveCell	PROC		EXPORT
			;Using	S_CurrentData

			input	Cell:l
			local	CellIndex:l,CellPtr:l,ContentIndex:l,DependIndex:l
			local	DependPtr:l,DNext:l,DLimit:l,Format:l,Value:l
			local	NextField:l,DependList:l,NextCell:l,Ptr:l
			BEGIN

			in		Cell:l
			out		CellIndex:l
			XCall	S_GetCellIndex

			ora		CellIndex
			jeq		Exit

			H_GetBlockPtr	CellIndex,CellPtr

			MoveLong	[CellPtr]:#S_CellFormat,Format
			MoveLong	[CellPtr]:#S_CellValue,Value
			MoveLong	[CellPtr]:#S_CellContent,ContentIndex
			MoveLong	[CellPtr]:#S_CellNext,NextField

			lda		ContentIndex
			ora		ContentIndex+2
			beq		contentGone

			lda		Format				; empty,pad-> no content
			and		#S_CellTypeTextForm		; text and value formulas
			beq		killContent

			Call		S_RemoveDependency,in=(Cell:l,ContentIndex:l)

			lda		Format
			and		#S_CellType
			cmp		#S_CellTypeTextForm		; text formula
			bne		killContent

;			lda		Format				; not necessary
;			and		#S_CellInvalid			; invalid cells are
;			bne		killContent			; typed as numeric

			H_DisposeBlock	Value

killContent
			H_DisposeBlock	ContentIndex
			H_GetBlockPtr	CellIndex,CellPtr

contentGone
			MoveWord	[CellPtr]:#S_CellDependOnMe,DependList
			sta		DependIndex

			MoveWord	[CellPtr]:#S_CellDependOnMe+2,DependList+2
			and		#$FFFF-S_CellTableFlags
			sta		DependIndex+2

			ora		DependIndex
			jeq		disposeIt

	;	If the cell is a non-user cell, i.e. pad-cell, then the value, priority,
	;	and circularity of other cells will not change.

			lda		Format
			jmi		disposeIt

			MoveWord	#0,[CellPtr]:#S_CellFormat+2
			MoveWord	a,[CellPtr]:#S_CellPriority

			lda		DependList+2
			bpl		doLoop

			Call		S_UpdatePriorities,in=(DependIndex:l)

			lda		S_LoadingFile
			bne		doDispose

			Call		S_ResetCircularBits,in=(DependIndex:l)
			Call		S_AddCellToChangedList,in=(DependIndex:l)

doDispose
			bra		disposeIt

doLoop
			MoveLong	#S_DependList,DNext

			H_GetBlockPtr	DependIndex,DependPtr

			MoveLong	[DependPtr],DLimit

priorityLoop
			AddLong	DependPtr,DNext,Ptr
			MoveLong	[Ptr],NextCell

			Call		S_UpdatePriorities,in=(NextCell:l)

			lda		S_LoadingFile
			bne		nextInLoop

			Call		S_ResetCircularBits,in=(NextCell:l)
			Call		S_AddCellToChangedList,in=(NextCell:l)			

nextInLoop
			AddLong	DNext,#S_DependInc,DNext
			CmpLong	DNext,DLimit
			blt		priorityLoop

disposeIt
			lda		NextField
			ora		NextField+2
			beq		killCell

	;	We have to wait to Deref PreviousCell, since we are adding cells
	;	to the changed list; one of them may alter this value.

			in		Cell:l,[CellPtr]:#S_CellPrevious:l,NextField:l
			XCall	S_RemoveCellFromChangedList

killCell

	;	If there are dependencies, then that is what I want to set into
	;	the cell table, otherwise set #0 (DependList == 0)

			Call			S_SetCellTableEntry,in=(Cell:l,DependList:l)
			H_DisposeBlock	CellIndex

			MoveWord	Format,a
			bmi		Exit

			lda		S_CurEditFlag
			and		#S_BRMostBit
			bne		Exit

			CmpWord	Cell,S_CurBRMost
			bge		findBRMost

			CmpWord	Cell+2,S_CurBRMost+2
			blt		Exit

findBRMost
			lda		#S_BRMostBit
			tsb		S_CurEditFlag

Exit
			RETURN
			ENDP

;-----------------------------------------------------------------------------
;	S_RemoveDependency( Cell:l, ContentIndex:l )
;

S_RemoveDependency	PROC		EXPORT
				;Using	S_CurrentData
				;Using	S_DependData

			input	Cell:l,ContentIndex:l
			local	ContentPtr:l,NumCells:w,CurCell:w
			local	RefType:w,TargetCell:l,TargetCell2:l
			BEGIN

			H_GetBlockPtr	ContentIndex,ContentPtr

			MoveWord	[ContentPtr]:#E_FormulaCells,NumCells
			MoveWord	#E_FormulaData,CurCell
			cmp		NumCells
			jge		Exit

loop
			MoveWord	[ContentPtr]:CurCell,a
			and		#$00FF
			sta		RefType

			and		#$0080
			jeq		singleRef

			iny
			in		[ContentPtr]:y:l,RefType:w,Cell:l
			out		TargetCell:l
			XCall	S_GetRealCell

			AddWord	CurCell,#5,CurCell
			tay

			CmpLong	TargetCell,#S_NotACell
			jeq		nextCell

			MoveWord	[ContentPtr]:y,a
			and		#$00FF
			sta		RefType

			iny
			in		[ContentPtr]:y:l,RefType:w,Cell:l
			out		TargetCell2:l
			XCall	S_GetRealCell

			CmpLong	TargetCell2,#S_NotACell
			beq		nextCell

			MoveLong	Cell,S_DependHomeCell

			Call		S_NormalizeRange,in=(TargetCell:l,TargetCell2:l)

			in		#S_RemoveRangeDep:l			; 2 inputs already on stack
			XCall	S_TraverseRange

			bra		nextCell

singleRef
			iny
			in		[ContentPtr]:y:l,RefType:w,Cell:l
			out		TargetCell:l
			XCall	S_GetRealCell

			CmpLong	TargetCell,#S_NotACell
			beq		nextCell

			Call		S_RemoveCellFromDepList,in=(Cell:l,TargetCell:l)

nextCell
			AddWord	CurCell,#5,CurCell
			cmp		NumCells
			bge		Exit

			H_GetBlockPtr	ContentIndex,ContentPtr
			brl			loop

Exit
			RETURN
			ENDP

;-----------------------------------------------------------------------------
;	S_InsertDependency( Cell:l, ContentIndex:l )
;

S_InsertDependency	PROC		EXPORT
				;Using	S_CurrentData
				;Using	S_DependData

			input	Cell:l,ContentIndex:l
			local	ContentPtr:l,NumCells:w,CurCell:w
			local	RefType:w,TargetCell:l,TargetCell2:l
			error	ErrFlag
			BEGIN

			stz		ErrFlag

			H_GetBlockPtr	ContentIndex,ContentPtr

			MoveWord	[ContentPtr]:#E_FormulaCells,NumCells
			MoveWord	#E_FormulaData,CurCell
			cmp		NumCells
			jge		Exit

loop
			MoveWord	[ContentPtr]:CurCell,a
			and		#$00FF
			sta		RefType

			and		#$0080
			jeq		singleRef

			iny
			in		[ContentPtr]:y:l,RefType:w,Cell:l
			out		TargetCell:l
			XCall	S_GetRealCell

			AddWord	CurCell,#5,CurCell
			tay

			CmpLong	TargetCell,#S_NotACell
			jeq		nextCell

			MoveWord	[ContentPtr]:y,a
			and		#$00FF
			sta		RefType

			iny
			in		[ContentPtr]:y:l,RefType:w,Cell:l
			out		TargetCell2:l
			XCall	S_GetRealCell

			CmpLong	TargetCell2,#S_NotACell
			beq		nextCell

			MoveLong	Cell,S_DependHomeCell

			Call		S_NormalizeRange,in=(TargetCell:l,TargetCell2:l)

			in		#S_EnterRangeDep:l			; 2 inputs already on stack
			XCall	S_TraverseRange,err=ErrFlag
			bcc		nextCell

			bra		gotError

singleRef
			iny
			in		[ContentPtr]:y:l,RefType:w,Cell:l
			out		TargetCell:l
			XCall	S_GetRealCell

			CmpLong	TargetCell,#S_NotACell
			beq		nextCell

			Call		S_AddCellToDepList,in=(Cell:l,TargetCell:l),err=ErrFlag
			bcs		gotError

nextCell
			AddWord	CurCell,#5,CurCell
			cmp		NumCells
			bge		Exit

			H_GetBlockPtr	ContentIndex,ContentPtr
			brl			loop

gotError
			Call		S_RemoveDependency,in=(Cell:l,ContentIndex:l)

Exit
			RETURN
			ENDP

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

S_DependData	PROC		EXPORT

				EXPORT	S_DependHomeCell

S_DependHomeCell	DS.B 	4

			ENDP


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

S_EnterRangeDep	PROC		EXPORT
				;Using	S_CurrentData
				;Using	S_DependData

			input	TargetCell:l
			local	CellIndex:l,CellPtr:l,DependPtr:l
			local	DependSize:l,NewSize:l,DependList:l
			local	DependRangeList:l,CellExists:w
			local	OtherCellInList:l
			error	ErrorFlag
			BEGIN

			stz		ErrorFlag
			stz		CellExists

			in		TargetCell:l
			out		CellIndex:l
			XCall	S_GetCellTableEntry

			ora		CellIndex
			beq		noDepsOnMe

			lda		CellIndex+2
			and		#S_CellTableFlags
			beq		targetExists

			MoveLong	CellIndex,DependList
			bra		depListExists

	;	The TagetCell is real, so we have to dereference it to get the
	;	depend list if there is one.

targetExists
			inc		CellExists

			H_GetBlockPtr	CellIndex,CellPtr

			MoveWord	[CellPtr]:#S_CellDependOnMe,DependList
			MoveWord	[CellPtr]:#S_CellDependOnMe+2,DependList+2

			ora		DependList
			bne		depListExists

	;	There are no previous DependOnMe's for this TargetCell
	;	We will Create a short list (type: Range)

noDepsOnMe
			MoveWord	S_DependHomeCell,DependList

			lda		S_DependHomeCell+2
			ora		#S_CellTableRangeDep
			sta		DependList+2

			lda		CellExists
			jeq		noCell
			brl		storeInCell

	;	Previous DependOnMe's exists, but we don't know how many and
	;	which type they are.

depListExists
			lda		DependList+2
			jpl		fullListExists

			and		#$FFFF-S_CellTableFlags
			sta		OtherCellInList+2
			MoveWord	DependList,OtherCellInList

			lda		DependList+2
			and		#S_CellTableFlags
			cmp		#S_CellTableSingDep
			beq		singleAndRange

	;	The previous list was only one range dependency reference.
	;	Make a full dep list.

			MoveLong	#S_DependList,DependRangeList
			bra		createList

	;	The previous list was only one single dependency reference.
	;	Make a full dep list.

singleAndRange
			MoveLong	#S_DependStructSize,DependRangeList

createList
			H_NewBlock	#S_DependStructSize+S_DependInc,DependList,DependPtr,err=ErrorFlag
			jcs			Exit

			MoveLong	#S_DependStructSize+S_DependInc,[DependPtr]:#S_DependSize
			MoveLong	DependRangeList,[DependPtr]:#S_DependRangeList

			MoveLong	OtherCellInList,[DependPtr]:#S_DependList
			MoveLong	S_DependHomeCell,[DependPtr]:#S_DependList+S_DependInc

			lda		DependList+2
			ora		#S_CellTableList
			sta		DependList+2

	;	Determine where to store the New DependList just created.

			lda		CellExists
			beq		noCell

			H_GetBlockPtr	CellIndex,CellPtr

storeInCell
			MoveLong	DependList,[CellPtr]:#S_CellDependOnMe
			brl		Exit

noCell
			in		TargetCell:l,DependList:l
			XCall	S_SetCellTableEntry,err=ErrorFlag
			brl		Exit


	;	A previous full DependOnMe list exists, put the New cell at the end

fullListExists
;			lda		DependList+2			; already in 'a'
			and		#-1-S_CellTableList
			sta		DependList+2

			H_GetBlockPtr	DependList,DependPtr

			MoveLong	[DependPtr]:#S_DependSize,DependSize
			AddLong	DependSize,#S_DependInc,NewSize

			H_ResizeBlock	DependList,NewSize,DependPtr,err=ErrorFlag
			bcs			Exit

			MoveLong	NewSize,[DependPtr]:#S_DependSize
			AddLong	DependSize,DependPtr,DependPtr
			MoveLong	S_DependHomeCell,[DependPtr]

Exit
			RETURN
			ENDP

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

S_RemoveRangeDep	PROC		EXPORT
				;Using	S_CurrentData
				;Using	S_DependData

			input	TargetCell:l
			local	CellIndex:l
			local	CellPtr:l,DependList:l,DependPtr:l
			local	DependSize:l,NewSize:l,NextPtr:l,LastPtr:l
			local	DependRangeList:l,CellExists:w,NewDependList:l
			error	ErrorFlag
			BEGIN

			stz		ErrorFlag
			stz		CellExists

			in		TargetCell:l
			out		CellIndex:l
			XCall	S_GetCellTableEntry

			ora		CellIndex
			beq		toError

			lda		CellIndex+2
			and		#S_CellTableFlags
			beq		targetExists

			MoveLong	CellIndex,DependList
			bra		depListExists

	;	The TargetCell is real, so we have to de-reference it to get the
	;	DependOnMe list, if there is one.

targetExists
			inc		CellExists

			H_GetBlockPtr	CellIndex,CellPtr

			MoveWord	[CellPtr]:#S_CellDependOnMe,DependList
			MoveWord	[CellPtr]:#S_CellDependOnMe+2,DependList+2

			ora		DependList
			bne		depListExists

toError
			brl		Error

	;	Previous DependOnMe's exist, but we don't know how many and of
	;	of which type they are.

depListExists
			lda		DependList+2
			bpl		fullListExists

	;	Only one previous DependOnMe.

			and		#S_CellTableFlags
			cmp		#S_CellTableSIngDep
			beq		toError

	;	It was a range reference, chk to see if it is the S_DependHomeCell

			lda		DependList+2
			and		#$FFFF-S_CellTableFlags
			cmp		S_DependHomeCell+2
			bne		toError

			CmpWord	DependList,S_DependHomeCell
			bne		toError

	;	It was, replace it with no list.

			stzl		NewDependList
			brl		storeDepList

	;	A previous full DependOnMe list exists, chk the following.
	;	1)	Are there any range references.
	;	2)	Are there more than two references.
	;	3)	Are there two range references, or one single and one range reference.

fullListExists
			lda		DependList+2
			and		#-1-S_CellTableList
			sta		DependList+2

			H_GetBlockPtr	DependList,DependPtr

			CmpLong	[DependPtr]:#S_DependRangeList,[DependPtr]:#S_DependSize
			jeq		Error

			CmpLong	#S_DependStructSize+S_DependInc,[DependPtr]:#S_DependSize
			jne		moreThanTwo

			CmpLong	[DependPtr]:#S_DependRangeList,#S_DependList+S_DependInc
			bne		twoRanges

	;	There is one single and one range reference, if the range reference
	;	is the S_DependHomeCell, then leave a short list (type: single)

			CmpLong	S_DependHomeCell,[DependPtr]:#S_DependList+S_DependInc
			jne		Error

			MoveWord	[DependPtr]:#S_DependList,NewDependList
			MoveWord	[DependPtr]:#S_DependList+2,a
			ora		#S_CellTableSingDep
			sta		NewDependList+2

			bra		killDepList

	;	There are two range references.  Check if either one is the S_DependHomeCell.
	;	If so, leave the other in a short list. (type: range)

twoRanges
			CmpLong	S_DependHomeCell,[DependPtr]:#S_DependList
			bne		notFirst

			MoveWord	[DependPtr]:#S_DependList+S_DependInc,NewDependList
			MoveWord	[DependPtr]:#S_DependList+S_DependInc+2,a

			bra		setRange

notFirst
			CmpLong	S_DependHomeCell,[DependPtr]:#S_DependList+S_DependInc
			jne		Error

			MoveWord	[DependPtr]:#S_DependList,NewDependList
			MoveWord	[DependPtr]:#S_DependList+2,a

setRange
			ora		#S_CellTableRangeDep
			sta		NewDependList+2

killDepList
			H_DisposeBlock		DependList

	;	Determine where to store the NewDependList

storeDepList
			lda		CellExists
			beq		noCell

			MoveLong	NewDependList,[CellPtr]:#S_CellDependOnMe
			brl		Exit

noCell
			Call		S_SetCellTableEntry,in=(TargetCell:l,NewDependList:l)
			brl		Exit




	;	There are more than two DependOnMe references.  Check if the S_DependHomeCell
	;	is in the range list, and remove it.

moreThanTwo
			MoveLong	[DependPtr]:#S_DependSize,DependSize
			MoveLong	[DependPtr]:#S_DependRangeList,DependRangeList

			AddLong	DependPtr,DependSize,LastPtr
			AddLong	DependPtr,DependRangeList,NextPtr

SearchLoop
			CmpLong	[NextPtr],S_DependHomeCell
			beq		found

			AddLong	NextPtr,#S_DependInc,NextPtr
			CmpLong	NextPtr,LastPtr
			blt		SearchLoop
			bra		Error

found
			SubLong	DependSize,#S_DependInc,NewSize
			MoveLong	NewSize,[DependPtr]:#S_DependSize

			AddLong	NextPtr,#S_DependInc,s
			PushLong	NextPtr
			AddLong	DependPtr,DependSize,s
			SubLong	1:s,NextPtr,1:s
			Tool		_BlockMove,in=(:l,:l,:l)

			H_ResizeBlock	DependList,NewSize

Error
Exit
			RETURN
			ENDP
			END

