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

		INCLUDE	'SS.equ'

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

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

		IMPORT	D_AlertBox
		IMPORT	D_MemoryError
	
		IMPORT	S_ActiveWindow
		IMPORT	S_AddCellToChangedList
		IMPORT	S_BadInsertMsg
		IMPORT	S_BadMoveMsg
		IMPORT	S_BadTransposeMsg
		IMPORT	S_BuildMoveUndo
		IMPORT	S_CalculateSheet
		IMPORT	S_ChkCellProtect
		IMPORT	S_ClearChangedBits
		IMPORT	S_ClearChangedBits2
		IMPORT	S_CurBRSelect
		IMPORT	S_CurDefFormat
		IMPORT	S_CurEditFlag
		IMPORT	S_CurTLSelect
		IMPORT	S_DependHomeCell
		IMPORT	S_DrawLocation
		IMPORT	S_EnterRangeDep
		IMPORT	S_ExtraData
		IMPORT	S_ExtraDataMsg
		IMPORT	S_FixFormula3
		IMPORT	S_FixLE
		IMPORT	S_GetCellDlog
		IMPORT	S_GetCellPtr
		IMPORT	S_GetCellTableEntry
		IMPORT	S_GetDirDlog
		IMPORT	S_GetRealCell
		IMPORT	S_GetRefCell
		IMPORT	S_HiliteCells
		IMPORT	S_InsertLeftPadCells
		IMPORT	S_InsertRightPadCells
		IMPORT	S_InvalidCellStr
		IMPORT	S_NoMoveReasonMsg
		IMPORT	S_NormalizeRange
		IMPORT	S_ProtectedCellMsg
		IMPORT	S_QRTraverseTable
		IMPORT	S_QTraverse
		IMPORT	S_QTraverseTable
		IMPORT	S_RearrangePadCells
		IMPORT	S_RedrawCellRange
		IMPORT	S_RemoveCell
		IMPORT	S_RemoveCellFromChangedList
		IMPORT	S_RemoveRangeDep
		IMPORT	S_ResetCircularity
		IMPORT	S_SetCellTableEntry
		IMPORT	S_SetCircularBits
		IMPORT	S_SetUndoOn
		IMPORT	S_SwapIn
		IMPORT	S_TransposeCell
		IMPORT	S_TrashCell
		IMPORT	S_TraverseDest
		IMPORT	S_TraverseRange
		IMPORT	S_UndoInProgress

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

		ENTRY	S_ChkContent
		ENTRY	S_DoMove
		ENTRY	S_DoTranspose
		ENTRY	S_DrawMove
		ENTRY	S_FixFormula
		ENTRY	S_FixFormula2
		ENTRY	S_FixFormulaFlag
		ENTRY	S_MergeDependLists
		ENTRY	S_MoveCell
		ENTRY	S_SplitDependList
		ENTRY	S_TraverseDependFormulas

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

S_MoveData	PROC		EXPORT

		EXPORT	S_DeltaMove
		EXPORT	S_MoveSrcTL
		EXPORT	S_MoveSrcBR
		EXPORT	S_MoveDestTL
		EXPORT	S_MoveDestBR
		EXPORT	S_OrigTransDestTL
		EXPORT	S_OrigTransDestBR
		EXPORT	S_MoveNewCell
		EXPORT	S_MoveOldCell

S_DeltaMove		DS.B 	4

S_MoveSrcTL		DS.B 	4
S_MoveSrcBR		DS.B 	4

S_MoveDestTL		DS.B 	4
S_MoveDestBR		DS.B 	4

S_OrigTransDestTL	DS.B 	4
S_OrigTransDestBR	DS.B 	4

S_MoveNewCell		DS.B 	4
S_MoveOldCell		DS.B 	4

			ENDP

;--------------------------------------------------------------------------
; S_Insert
;

S_Insert		PROC		EXPORT
			;Using	S_CurrentData
			;Using	S_MoveData
			;Using	S_ErrorData

			local	TrashTL:l,TrashBR:l,DoTrash:w
			error	ErrFlag
			BEGIN	+b

			stz		ErrFlag
			stz		DoTrash

			Call		S_SwapIn,in=(S_ActiveWindow:l)

chkRowSelected
			lda		S_CurTLSelect+2
			cmp		#1
			bne		chkColSelected

			lda		S_CurBRSelect+2
			cmp		#702
			beq		shiftDown

chkColSelected
			lda		S_CurTLSelect
			cmp		#1
			bne		askDirection

			lda		S_CurBRSelect
			cmp		#9999
			jeq		shiftRight

askDirection

	;	direction: 0==Cancel,1==Left,2==Right,3==Up,4==Down

			Call		S_GetDirDlog,in=(#1:w),out=(a:w)

			jeq		Exit				; = cancel

			cmp		#2				; = right
			jeq		shiftRight

			cmp		#4				; = down
			jne		Exit

shiftDown
			SubWord	S_CurBRSelect,S_CurTLSelect,a
			inc		a
			sta		S_DeltaMove
			stz		S_DeltaMove+2

			MoveWord	S_CurTLSelect+2,TrashTL+2
			SubWord	#10000,S_DeltaMove,TrashTL
			MoveWord	S_CurBRSelect+2,TrashBR+2
			MoveWord	#9999,TrashBR

			Call		S_QTraverse,in=(TrashTL:l,TrashBR:l,#S_ChkContent:l)
			bcs		badInsert

			CmpWord	S_CurBRSelect,TrashTL
			blt		doMoveOnly

			cmp		#9999
			jge		doTrashRect

			sta		TrashBR
			inc		DoTrash

doMoveOnly
			MoveLong	S_CurTLSelect,S_MoveSrcTL

			SubWord	#9999,S_DeltaMove,S_MoveSrcBR
			MoveWord	S_CurBRSelect+2,S_MoveSrcBR+2

			bra		doInsert

shiftRight
			stz		S_DeltaMove
			SubWord	S_CurBRSelect+2,S_CurTLSelect+2,a
			inc		a
			sta		S_DeltaMove+2

			SubWord	#703,S_DeltaMove+2,TrashTL+2
			MoveWord	S_CurTLSelect,TrashTL
			MoveWord	#702,TrashBR+2
			MoveWord	S_CurBRSelect,TrashBR

			Call		S_QTraverse,in=(TrashTL:l,TrashBR:l,#S_ChkContent:l)
			bcc		chkArea2

badInsert
			Call		D_AlertBox,in=(#OKBox:w,#S_BadInsertMsg:l),out=(a:w)
			bra		Exit

chkArea2
			CmpWord	S_CurBRSelect+2,TrashTL+2
			blt		doMoveOnly2

			cmp		#702
			bge		doTrashRect

			sta		TrashBR+2
			inc		DoTrash

doMoveOnly2
			MoveLong	S_CurTLSelect,S_MoveSrcTL

			MoveWord	S_CurBRSelect,S_MoveSrcBR
			SubWord	#702,S_DeltaMove+2,S_MoveSrcBR+2

doInsert
			Call		S_DoMove,err=ErrFlag
			bcc		finish

			and		#$FF00
			cmp		#$0200
			bne		Exit

			Call		D_MemoryError
			bra		setUndo

finish
			lda		DoTrash
			beq		setUndo

doTrashRect
			in		TrashTL:l,TrashBR:l,#S_TrashCell:l
			XCall	S_QTraverseTable,err=ErrFlag

setUndo
			Call		S_DrawMove
			Call		S_SetUndoOn,in=(#S_UndoInsertType:w)

			lda		S_CurEditFlag
			and		#S_ManCalcBit
			bne		Exit

			Call		S_CalculateSheet

Exit
			RETURN
			ENDP

;--------------------------------------------------------------------------
; S_Delete
;

S_Delete		PROC		EXPORT
			;Using	S_CurrentData
			;Using	S_MoveData

			error	ErrFlag
			BEGIN	+b

			stz		ErrFlag

			Call		S_SwapIn,in=(S_ActiveWindow:l)

chkRowSelected
			lda		S_CurTLSelect+2
			cmp		#1
			bne		chkColSelected

			lda		S_CurBRSelect+2
			cmp		#702
			beq		shiftUp

chkColSelected
			lda		S_CurTLSelect
			cmp		#1
			bne		askDirection

			lda		S_CurBRSelect
			cmp		#9999
			beq		shiftLeft

askDirection

	;	direction: 0==Cancel,1==Left,2==Right,3==Up,4==Down

			Call		S_GetDirDlog,in=(#2:w),out=(a:w)

			jeq		Exit				; = cancel

			cmp		#1				; = left
			beq		shiftLeft

			cmp		#3				; = up
			jne		Exit

shiftUp
			SubWord	S_CurTLSelect,S_CurBRSelect,a
			dec		a
			sta		S_DeltaMove
			MoveWord	#0,S_DeltaMove+2

			lda		S_CurBRSelect
			inc		a
			sta		S_MoveSrcTL
			MoveWord	S_CurTLSelect+2,S_MoveSrcTL+2

			SubWord	#9999,S_DeltaMove,S_MoveSrcBR
			MoveWord	S_CurBRSelect+2,S_MoveSrcBR+2

			bra		doDelete

shiftLeft
			stz		S_DeltaMove
			SubWord	S_CurTLSelect+2,S_CurBRSelect+2,a
			dec		a
			sta		S_DeltaMove+2

			MoveWord	S_CurTLSelect,S_MoveSrcTL
			lda		S_CurBRSelect+2
			inc		a
			sta		S_MoveSrcTL+2

			MoveWord	S_CurBRSelect,S_MoveSrcBR
			SubWord	#702,S_DeltaMove+2,S_MoveSrcBR+2

doDelete
			Call		S_DoMove,err=ErrFlag
			bcc		redraw

			and		#$FF00
			cmp		#$0200
			bne		Exit

			Call		D_MemoryError

redraw
			Call		S_DrawMove
			Call		S_SetUndoOn,in=(#S_UndoDeleteType:w)

			lda		S_CurEditFlag
			and		#S_ManCalcBit
			bne		Exit

			Call		S_CalculateSheet

Exit
			RETURN
			ENDP

;----------------------------------------------------------
; S_Move
;

S_Move		PROC		EXPORT
			;Using	S_CurrentData
			;Using	S_MoveData
			;Using	S_ErrorData

			local	DestCell:l
			error	ErrFlag
			BEGIN	+b

			stz		ErrFlag

			Call		S_SwapIn,in=(S_ActiveWindow:l)

	;	newcell: 0 == Cancelled, 0 w/carry set == error

			Call		S_GetCellDlog,in=(#1:w,#0:l),out=(DestCell:l)

			bcc		doOK

			Call		D_AlertBox,in=(#OKBox:w,#S_InvalidCellStr:l),out=(a:w)

doOK
			lda		DestCell
			ora		DestCell+2
			jeq		Exit

			SubWord	DestCell,S_CurTLSelect,S_DeltaMove
			SubWord	DestCell+2,S_CurTLSelect+2,S_DeltaMove+2

			lda		S_DeltaMove
			ora		S_DeltaMove+2
			bne		contMove

			Call		D_AlertBox,in=(#OkBox:w,#S_NoMoveReasonMsg:l),out=(a:w)
			bra		Exit

contMove
			MoveLong	S_CurTLSelect,S_MoveSrcTL
			MoveLong	S_CurBRSelect,S_MoveSrcBR

			Call		S_DoMove,err=ErrFlag
			bcc		doHilite

			and		#$FF00
			cmp		#$0200
			bne		Exit

			Call		D_MemoryError

doHilite
			Call		S_HiliteCells

			AddWord	S_CurTLSelect+2,S_DeltaMove+2,S_CurTLSelect+2
			AddWord	S_CurTLSelect,S_DeltaMove,S_CurTLSelect
			AddWord	S_CurBRSelect+2,S_DeltaMove+2,S_CurBRSelect+2
			AddWord	S_CurBRSelect,S_DeltaMove,S_CurBRSelect

			Call		S_HiliteCells

			Call		S_DrawMove
			Call		S_DrawLocation

			Call		S_SetUndoOn,in=(#S_UndoMoveType:w)

			lda		S_CurEditFlag
			and		#S_ManCalcBit
			bne		Exit

			Call		S_CalculateSheet

Exit
			RETURN
			ENDP

;--------------------------------------------------------------------------
; S_Transpose
;

S_Transpose	PROC		EXPORT
			;Using	S_CurrentData
			;Using	S_MoveData

			error	ErrFlag
			BEGIN	+b

			stz		ErrFlag

			Call		S_SwapIn,in=(S_ActiveWindow:l)

			MoveLong	S_CurTLSelect,S_MoveSrcTL
			MoveLong	S_CurBRSelect,S_MoveSrcBR

			Call		S_DoTranspose,err=ErrFlag
			bcc		setUndo

			and		#$FF00
			cmp		#$0200
			bne		Exit

			Call		D_MemoryError

setUndo
			Call		S_SetUndoOn,in=(#S_UndoTransposeType:w)

			MoveLong	S_OrigTransDestTL,S_CurTLSelect
			MoveLong	S_OrigTransDestBR,S_CurBRSelect

			in		S_MoveSrcTL:l,S_MoveSrcBR:l
			XCall	S_RedrawCellRange

			in		S_MoveDestTL:l,S_MoveDestBR:l
			XCall	S_RedrawCellRange

			lda		S_CurEditFlag
			and		#S_ManCalcBit
			bne		Exit

			Call		S_CalculateSheet

Exit
			RETURN
			ENDP

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

S_DoMove		PROC		EXPORT
			;Using	S_CurrentData
			;Using	S_MoveData
			;Using	S_ErrorData
			;Using	S_UndoData

			local	SrcTL:l,SrcBR:l,CellPtr:l
			error	ErrFlag
			BEGIN

			stz		ErrFlag

			lda		#S_BRMostBit
			tsb		S_CurEditFlag

			MoveWord	S_MoveSrcTL+2,SrcTL+2
			AddWord	a,S_DeltaMove+2,S_MoveDestTL+2

			MoveWord	S_MoveSrcTL,SrcTL
			AddWord	a,S_DeltaMove,S_MoveDestTL

			MoveWord	S_MoveSrcBR+2,SrcBR+2
			AddWord	a,S_DeltaMove+2,S_MoveDestBR+2

			MoveWord	S_MoveSrcBR,SrcBR
			AddWord	a,S_DeltaMove,S_MoveDestBR

			ldx		S_UndoInProgress
			bne		chkProtect

			cmp		#10000
			bge		badMove

			CmpWord	S_MoveDestBR+2,#703
			blt		chkProtect

badMove
			inc		ErrFlag
			Call		D_AlertBox,in=(#OkBox:w,#S_BadMoveMsg:l),out=(a:w)
			brl		Exit

	;	Chk destination for protected cells	;

chkProtect
;			Call		D_SetCursor,in=(#WatchCursor:w)

			stz		S_ExtraData

			in		S_MoveSrcTL:l,S_MoveSrcBR:l
			in		S_MoveDestTL:l,S_MoveDestBR:l,#S_ChkCellProtect:l
			XCall	S_TraverseDest,err=ErrFlag

			bcc		chkExtraData

			inc		ErrFlag
			Call		D_AlertBox,in=(#OkBox:w,#S_ProtectedCellMsg:l),out=(a:w)
			brl		Exit

chkExtraData
			lda		S_ExtraData
			beq		contMove

			Call		D_AlertBox,in=(#OkCancelBox:w,#S_ExtraDataMsg:l),out=(a:w)

			cmp		#OK
			beq		contMove

			inc		ErrFlag
			brl		Exit

contMove
			Call		S_BuildMoveUndo,err=ErrFlag
			bcs		Exit

			in		SrcTL:l,SrcBR:l
			in		S_MoveDestTL:l,S_MoveDestBR:l,#S_TrashCell:l
			XCall	S_TraverseDest,err=ErrFlag
			bcs		Exit

			lda		S_DeltaMove
			bmi		doForward
			bne		doBackward

			lda		S_DeltaMove+2
			bmi		doForward

doBackward
			in		SrcTL:l,SrcBR:l,#S_MoveCell:l
			XCall	S_QRTraverseTable,err=ErrFlag
			bra		Exit

doForward
			in		SrcTL:l,SrcBR:l,#S_MoveCell:l
			XCall	S_QTraverseTable,err=ErrFlag

Exit
			RETURN
			ENDP

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

S_DrawMove	PROC		EXPORT
			;Using	S_CurrentData
			;Using	S_MoveData

			BEGIN

			CmpWord	S_MoveSrcBR,#10000
			blt		okSrcB

			MoveWord	#9999,S_MoveSrcBR
okSrcB

			CmpWord	S_MoveSrcBR+2,#703
			blt		okSrcR

			MoveWord	#702,S_MoveSrcBR+2
okSrcR

			in		S_MoveSrcTL:l,S_MoveSrcBR:l
			XCall	S_RedrawCellRange

			in		S_MoveDestTL:l,S_MoveDestBR:l
			XCall	S_RedrawCellRange

redrawLE
			Call		S_FixLE

			RETURN
			ENDP

;----------------------------------------------------------
; S_DoTranspose
;

S_DoTranspose	PROC		EXPORT
			;Using	S_CurrentData
			;Using	S_MoveData
			;Using	S_ErrorData
			;Using	S_UndoData

			error	ErrFlag
			BEGIN

			stz		ErrFlag
			stz		S_ExtraData

			lda		#S_BRMostBit
			tsb		S_CurEditFlag

			MoveLong	S_MoveSrcTL,S_MoveDestTL

			SubWord	S_MoveSrcBR+2,S_MoveSrcTL+2,a
			AddWord	a,S_MoveSrcTL,S_MoveDestBR

			SubWord	S_MoveSrcBR,S_MoveSrcTL,a
			AddWord	a,S_MoveSrcTL+2,S_MoveDestBR+2

			MoveLong	S_MoveDestTL,S_OrigTransDestTL
			MoveLong	S_MoveDestBR,S_OrigTransDestBR

	;	ChkDest for protected cells or off sheet	;

			cmp		#703
			bge		offSheet

			CmpWord	S_MoveDestBR,#10000
			blt		onSheet

offSheet
			inc		ErrFlag
			Call		D_AlertBox,in=(#OkBox:w,#S_BadTransposeMsg:l),out=(a:w)
			brl		Exit

onSheet
			CmpWord	S_MoveDestBR,S_MoveSrcBR			; rows only
			beq		chkDone
			bge		horz2Vert

			lda		S_MoveSrcBR+2
			inc		a
			pha
			PushWord	S_MoveSrcTL
			bra		doChk

horz2Vert
			PushWord	S_MoveSrcTL+2
			lda		S_MoveSrcBR
			inc		a
			pha

doChk
;			Call		D_SetCursor,in=(#WatchCursor:w)

			in		S_MoveDestBR:l,#S_ChkCellProtect:l		; long on stack
			XCall	S_QTraverse

			bcc		chkExtraData

			inc		ErrFlag
			Call		D_AlertBox,in=(#OkBox:w,#S_ProtectedCellMsg:l),out=(a:w)
			brl		Exit

chkExtraData
			lda		S_ExtraData
			beq		chkDone

			Call		D_AlertBox,in=(#OkCancelBox:w,#S_ExtraDataMsg:l),out=(a:w)

			cmp		#OK
			beq		chkDone

			inc		ErrFlag
			brl		Exit

chkDone
			Call		S_BuildMoveUndo,err=ErrFlag
			bcs		Exit

			in		S_MoveSrcTL:l,S_MoveSrcBR:l
			in		S_MoveDestTL:l,S_MoveDestBR:l,#S_TrashCell:l
			XCall	S_TraverseDest,err=ErrFlag
			bcs		Exit

			in		S_MoveSrcTL:l,S_MoveSrcBR:l,#S_TransposeCell:l
			XCall	S_TraverseRange,err=ErrFlag

Exit
			RETURN
			ENDP

;----------------------------------------------------------
; S_MoveCell
;

S_MoveCell	PROC		EXPORT
			;Using	S_CurrentData
			;Using	S_MoveData

			input	Cell:l,SrcCellTableEntry:l
			local	ClrSrcFlag:w,TestCirc:w
			local	FakeSrcFlag:w,FakeDestFlag:w,DestExists:w
			local	SrcCellType:w,SrcCellFormat:l,FormulaIndex:l
			local	PreviousField:l,NextField:l
			local	DependIndex:l,DestDepList:l,NewDepList:l,EntryToLeave:l
			local	SingleDeps:l,RangeDeps:l,DestCellTableEntry:l,CellPtr:l
			error	ErrorFlag
			BEGIN

	ProfileIn		2

	;	Initialize flag variables

			stz		ErrorFlag
			stz		ClrSrcFlag
			stz		TestCirc
			stz		S_FixFormulaFlag		; for fixing formulas in S_FixFormula routines

	;	Globalize the Source and Destination Cells

			MoveWord	Cell,S_MoveOldCell
			AddWord	a,S_DeltaMove,S_MoveNewCell

			MoveWord	Cell+2,S_MoveOldCell+2
			AddWord	a,S_DeltaMove+2,S_MoveNewCell+2

	;	Determine the Situation:  (i.e. Cell types of both the dest and 
	;	src cells after the move.)

	;	This is accomplished by looking at both the src and dest
	;	cells at the beginning of the routine and using the least
	;	common denominator.

	;	We will also initalize several local variables while we are
	;	looking at the cells.

			lda		SrcCellTableEntry+2
			and		#S_CellTableFlags
			sta		FakeSrcFlag			; (re)set this flag for later use.
			beq		startRealSrc

			MoveWord	#S_CellTypeEmpty,SrcCellType
			MoveWord	#0,SrcCellFormat+2

			MoveLong	SrcCellTableEntry,DependIndex
			brl		adjustDepend

startRealSrc
			H_GetBlockPtr	SrcCellTableEntry,CellPtr

			MoveLong	[CellPtr]:#S_CellDependOnMe,DependIndex
			MoveLong	[CellPtr]:#S_CellNext,NextField
			MoveLong	[CellPtr]:#S_CellPrevious,PreviousField
			MoveWord	[CellPtr]:#S_CellFormat+2,SrcCellFormat+2

			MoveWord	[CellPtr]:#S_CellFormat,SrcCellFormat
			and		#S_CellType
			sta		SrcCellType
			bpl		doRealCell

			lda		DependIndex		; if this jumps to exit, then
			ora		DependIndex+2		; the cell was only a pad cell
			bne		chkChangedLst		; with no dependencies.

			brl		Exit

	;	While looking at a real src cell, adjust the cell's id

doRealCell
			MoveLong	[CellPtr]:#S_CellContent,FormulaIndex
			MoveLong	S_MoveNewCell,[CellPtr]:#S_CellID

	;	Remove the original cell from the ChangedList, it won't be
	;	in the same location

chkChangedLst
			lda		NextField
			ora		NextField+2
			beq		adjustDepend

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

			in		Cell:l,PreviousField:l,NextField:l
			XCall	S_RemoveCellFromChangedList


	;	Adjust the cell's DependOnMe references		;
	;	This is now before adjusting the formula,	;
	;	because of circular formulas				;

adjustDepend
			lda		DependIndex
			ora		DependIndex+2
			beq		chkFormula

			lda		SrcCellFormat+2
			and		#S_CellCircular
			beq		doTraverse

			MoveWord	#S_RecentlyChangedBit2,S_FixFormulaFlag
			inc		ClrSrcFlag

doTraverse
			in		Cell:l,SrcCellTableEntry:l
			in		#S_FixFormula:l,#S_FixFormula2:l
			XCall	S_TraverseDependFormulas


chkFormula
			lda		SrcCellType
			bmi		breakDepends

			and		#S_CellTypeTextForm					; any formula
			beq		breakDepends

	;	Adjust the cell's formula	;

			in		Cell:l,S_MoveNewCell:l,FormulaIndex:l
			XCall	S_FixFormula3

			lda		ClrSrcFlag
			beq		breakDepends

	;	Clear the FixFormula Circular bits that were stuck into the formulas
	;	during the FixFormula pass.  We know that SrcCellTableEntry is still
	;	good, because Cell is a real cell containing a formula.

			in		Cell:l,SrcCellTableEntry:l
			in		#S_ClearChangedBits:l,#S_ClearChangedBits2:l
			XCall	S_TraverseDependFormulas

			Call		S_ClearChangedBits,in=(Cell:l,FormulaIndex:l)


	;	Break up depend list into its single cell and range parts.
	;	The single part will be attached to new location's range part
	;	and the original range part left at this location.

breakDepends
			lda		FakeSrcFlag
			beq		startRealSrc2

	;	This is where we will correct SrcCellTableEntry, if it was altered
	;	by the FixFormula routines.

			in		Cell:l
			out		:l
			XCall	S_GetCellTableEntry

			pla
			sta		DependIndex
			sta		SrcCellTableEntry

			pla
			sta		DependIndex+2
			sta		SrcCellTableEntry+2

			ora		DependIndex
			bne		gotDepList

			brl		insertNewCell			; this only happens when the only
										; dependency is a range endpt.


startRealSrc2
			H_GetBlockPtr	SrcCellTableEntry,CellPtr

			MoveLong	[CellPtr]:#S_CellDependOnMe,DependIndex

gotDepList
			in		DependIndex:l
			out		SingleDeps:l,RangeDeps:l
			XCall	S_SplitDependList

	;	Adjust the cell's location	;

			in		S_MoveNewCell:l
			out		DestCellTableEntry:l
			XCall	S_GetCellTableEntry

			ora		DestCellTableEntry
			sta		DestExists
			beq		doDestEmpty

			lda		DestCellTableEntry+2
			and		#S_CellTableFlags
			sta		FakeDestFlag
			beq		doPadDest2

	;	What follows works for both empty and fake cells

doDestEmpty
			MoveLong	DestCellTableEntry,DestDepList
			bra		gotDestDepList

	;	The destination cell has already been trashed. Only range
	;	references can remain.  (This must be a pad cell.)

doPadDest2
			H_GetBlockPtr	DestCellTableEntry,CellPtr

			MoveWord	[CellPtr]:#S_CellDependOnMe,DestDepList
			MoveWord	#0,[CellPtr]:y
			iny
			iny
			MoveWord	[CellPtr]:y,DestDepList+2
			MoveWord	#0,[CellPtr]:y

	;	Take an initial guess of the EntryToLeave, and merge the
	;	dep lists.  (Where to store it depends on the cell types.)

gotDestDepList
			MoveLong	RangeDeps,EntryToLeave

			in		SingleDeps:l,DestDepList:l
			out		NewDepList:l
			XCall	S_MergeDependLists

	;	Look at the Src type and see if guess was right.

			lda		FakeSrcFlag
			bne		setDestCell			; guessed EntryToLeave right!

			lda		SrcCellType
			bpl		moveRealSrc			; guessed EntryToLeave right!

	;	Guessed EntryToLeave wrong!
	;
	;	We are leaving a Pad Cell behind!

			H_GetBlockPtr	SrcCellTableEntry,CellPtr

			MoveLong	RangeDeps,[CellPtr]:#S_CellDependOnMe
			MoveLong	SrcCellTableEntry,EntryToLeave

	;	Now we look at the Dest cell type to determine how to
	;	set the destination cell.

setDestCell
			lda		DestExists
			beq		storeDepList

			lda		FakeDestFlag
			beq		storeDepsInDest

	;	We are creating a fake dest cell with the NewDepList
	;

storeDepList
			MoveLong	NewDepList,SrcCellTableEntry
			bra		resetIndices

	;	We must store the NewDepList in the Pad cell.

storeDepsInDest
			H_GetBlockPtr	DestCellTableEntry,CellPtr

			MoveLong	NewDepList,[CellPtr]:#S_CellDependOnMe
			MoveLong	DestCellTableEntry,SrcCellTableEntry
			bra		resetIndices


	;	When moving a Real Src Cell, the following code should be used
	;	instead of the previous 'case' statement.

moveRealSrc
			lda		DestExists
			beq		storeDepsInSrc

			lda		FakeDestFlag
			bne		storeDepsInSrc

	;	If the dest is a Pad cell, it needs to be disposed of.

			Call		S_RemoveCell,in=(S_MoveNewCell:l)

storeDepsInSrc
			H_GetBlockPtr	SrcCellTableEntry,CellPtr

			MoveLong	NewDepList,[CellPtr]:#S_CellDependOnMe
			inc		TestCirc

resetIndices
			Call		S_SetCellTableEntry,in=(Cell:l,EntryToLeave:l)
			Call		S_SetCellTableEntry,in=(S_MoveNewCell:l,SrcCellTableEntry:l)

	;	If cell is label, fix pad cells: if cell is formula, fix
	;	circularity

			lda		SrcCellType
			jmi		chkSrcCell

			and		#S_CellTypeTextForm			; any formula
			beq		fixPadCells

			lda		SrcCellFormat+2
			and		#S_CellCircular
			beq		setCircular

			lda		RangeDeps+2				; only reset circular if
			ora		RangeDeps					; a formula is moved out
			beq		setCircular				; of a range

			Call		S_ResetCircularity,in=(Cell:l)

setCircular
			lda		DestDepList+2				; only chk circular if
			ora		DestDepList				; a formula is moved into
			beq		fixPadCells				; a range

			Call		S_SetCircularBits,in=(S_MoveNewCell:l)

	;	Remove old pad cells	;

fixPadCells
			in		S_MoveNewCell:l
			out		:l,:l
			XCall	S_RearrangePadCells,err=ErrorFlag

			pla
			plx

			cpx		S_MoveDestBR+2
			blt		chkLeft1

			stx		S_MoveDestBR+2

chkLeft1
			pla
			plx

			cpx		S_MoveDestTL+2
			bge		removeSrcPads

			stx		S_MoveDestTL+2

removeSrcPads
			lda		ErrorFlag
			jne		chkSrcCell

			in		Cell:l
			out		:l,:l
			XCall	S_RearrangePadCells,err=ErrorFlag

			pla
			plx

			cpx		S_MoveSrcBR+2
			blt		chkLeft2

			stx		S_MoveSrcBR+2

chkLeft2
			pla
			plx

			cpx		S_MoveSrcTL+2
			bge		chkForLabel

			stx		S_MoveSrcTL+2

	;	Insert New pad cells	;

chkForLabel
			lda		ErrorFlag
			bne		chkSrcCell

			lda		SrcCellType
			bne		chkSrcCell			 	; 0 = label

			Call		S_InsertRightPadCells,in=(S_MoveNewCell:l),out=(ax:l)

			cpx		S_MoveDestBR+2
			blt		chkLeft3

			stx		S_MoveDestBR+2

chkLeft3
			Call		S_InsertLeftPadCells,in=(S_MoveNewCell:l),out=(ax:l)

			cpx		S_MoveDestTL+2
			bge		chkSrcCell

			stx		S_MoveDestTL+2

chkSrcCell
			lda		EntryToLeave
			ora		EntryToLeave+2
			beq		chkDestCell

			Call		S_AddCellToChangedList,in=(Cell:l)

chkDestCell
			lda		SrcCellTableEntry
			ora		SrcCellTableEntry+2
			beq		Exit

insertNewCell
			Call		S_AddCellToChangedList,in=(S_MoveNewCell:l)

Exit

	ProfileOut	2

			RETURN
			ENDP

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

S_SplitDependList	PROC		EXPORT
				;Using	S_CurrentData

			input	OldDependList:l
			output	SingleDeps:l,RangeDeps:l
			local	DependList:l,DependPtr:l,RangeDepPtr:l
			local	RangeStart:l,RangeSize:l
			local	RangeIndexSize:l
			error	ErrorFlag
			BEGIN

			stz		ErrorFlag

			stz		RangeDeps+2
			stz		RangeDeps
			stz		SingleDeps+2
			stz		SingleDeps

			lda		OldDependList+2
			ora		OldDependList
			jeq		Exit								; branch no Dep list

			lda		OldDependList+2
			bpl		doFullDepList						; branch full Dep list

			and		#S_CellTableFlags
			cmp		#S_CellTableRangeDep
			beq		allRangeDeps						; branch short range Dep

	;	The incoming list was all single references, hence this original
	;	list is the outgoing SingleDeps.  (RangeDeps = 0)

allSingleDeps
			MoveLong	OldDependList,SingleDeps
			brl		Exit

	;	The incoming list was all range references, hence this original
	;	list is the outgoing RangeDeps.  (SingleDeps = 0)

allRangeDeps
			MoveLong	OldDependList,RangeDeps
			brl		Exit

doFullDepList
			MoveWord	OldDependList,DependList
			lda		OldDependList+2
			and		#$FFFF-S_CellTableFlags
			sta		DependList+2

			H_GetBlockPtr	DependList,DependPtr

			MoveLong	[DependPtr]:#S_DependRangeList,RangeStart

	;	Check if the full list is homogenous (i.e. all ranges or all singles)

			CmpLong	RangeStart,[DependPtr]
			beq		allSingleDeps				; brange no range deps

			CmpLong	RangeStart,#S_DependList
			beq		allRangeDeps				; branch all range deps

	;	The original list contains both single and range deps
	;	If there is only one single dep or one range dep, Create
	;	short dep lists

			CmpLong	RangeStart,#S_DependList+S_DependInc
			jne		moreThanOneSingle

	;	There is only one single dependency.  It will be a short list.

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

	;	Check if there are more than one range dependencies.

			CmpLong	[DependPtr],#S_DependList+S_DependInc+S_DependInc
			bne		moreThanOneRange

	;	Yes, kill the old dep list.

			MoveWord	[DependPtr]:#S_DependList+S_DependInc,RangeDeps
			MoveWord	[DependPtr]:#S_DependList+S_DependInc+2,a
			ora		#S_CellTableRangeDep
			sta		RangeDeps+2

			H_DisposeBlock	DependList
			brl			Exit

	;	Since the range part of the list is a full list, but the single
	;	part is not, we must move the data up and shorten the heap block.

moreThanOneRange
			MoveLong	OldDependList,RangeDeps

			SubLong	[DependPtr],RangeStart,RangeSize
			SubLong	[DependPtr],#S_DependInc,RangeIndexSize

			MoveLong	RangeIndexSize,[DependPtr]
			MoveLong	#S_DependList,[DependPtr]:#S_DependRangeList

			AddLong	DependPtr,#S_DependList+S_DependInc,s
			AddLong	DependPtr,#S_DependList,s
			PushLong	RangeSize
			Tool		_BlockMove,in=(:l,:l,:l)

			H_ResizeBlock	DependList,RangeIndexSize	; resize smaller always works
			brl			Exit

	;	The single part is a full list, so we will have to shorten the
	;	original dep list.  But first we must handle the range part.

moreThanOneSingle
			MoveLong	OldDependList,SingleDeps
			SubLong	[DependPtr],RangeStart,RangeSize

			CmpLong	RangeSize,#S_DependInc
			bne		moreThanOneOfBoth

	;	Only one range dep, so make a short list.

			AddLong	DependPtr,RangeStart,RangeDepPtr

			MoveWord	[RangeDepPtr],RangeDeps
			MoveWord	[RangeDepPtr]:#2,a
			ora		#S_CellTableRangeDep
			sta		RangeDeps+2

			brl		fixSingleDeps

	;	The range list is also a full list.  Create a block and copy the
	;	range part into it.

moreThanOneOfBoth
			AddLong	RangeSize,#S_DependList,RangeIndexSize

			H_NewBlock	RangeIndexSize,RangeDeps,RangeDepPtr,err=ErrorFlag
			jcs			Exit

			MoveLong	RangeIndexSize,[RangeDepPtr]
			MoveLong	#S_DependList,[RangeDepPtr]:#S_DependRangeList

			H_GetBlockPtr	DependList,DependPtr

			AddLong	DependPtr,RangeStart,s
			AddLong	RangeDepPtr,#S_DependList,s
			PushLong	RangeSize
			Tool		_BlockMove,in=(:l,:l,:l)

			lda		RangeDeps+2
			ora		#S_CellTableList
			sta		RangeDeps+2

	;	Fix SingleDeps block.

fixSingleDeps
			MoveLong		RangeStart,[DependPtr]
			H_ResizeBlock	DependList,RangeStart		; resize smaller always works

Exit
			RETURN
			ENDP

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

S_MergeDependLists	PROC		EXPORT
				;Using	S_CurrentData

			input	SingleDeps:l,RangeDeps:l
			output	NewDepList:l
			local	SingleDepSize:l,SingleDepPtr:l
			local	RangeDepSize:l,RangeDepPtr:l
			local	NewDepSize:l,NewDepPtr:l,WhichList:w
			error	ErrorFlag
			BEGIN

			stz		ErrorFlag
			stz		WhichList

			stz		NewDepList
			stz		NewDepList+2

			lda		SingleDeps
			ora		SingleDeps+2
			beq		noSingleDeps

			lda		RangeDeps
			ora		RangeDeps+2
			bne		bothDepsExist

	;	There are no range deps, so the merge only yields the single deps

			MoveLong	SingleDeps,NewDepList
			brl		Exit

	;	There are no single deps, so the merge only yields the range deps

noSingleDeps
			MoveLong	RangeDeps,NewDepList
			brl		Exit

	;	Both kinds of deps are party to the merge.
	;	First figure the New size needed to hold the New
	;	dependency list

bothDepsExist
			lda		SingleDeps+2
			bpl		fullSingle

			MoveLong	#S_DependStructSize,SingleDepSize
			bra		gotSingleSize

fullSingle
			and		#$FFFF-S_CellTableFlags		; won't change the high bit
			sta		SingleDeps+2

			MoveWord	#$8000,WhichList

			H_GetBlockPtr	SingleDeps,SingleDepPtr

			MoveLong	[SingleDepPtr],SingleDepSize

gotSingleSize
			lda		RangeDeps+2
			bpl		fullRange

			MoveLong	#S_DependStructSize,RangeDepSize
			bra		gotRangeSize

fullRange
			and		#$FFFF-S_CellTableFlags		; won't change the high bit
			sta		RangeDeps+2

			inc		WhichList

			H_GetBlockPtr	RangeDeps,RangeDepPtr

			MoveLong	[RangeDepPtr],RangeDepSize

gotRangeSize
			AddLong	SingleDepSize,RangeDepSize,NewDepSize
			SubLong	NewDepSize,#S_DependList,NewDepSize

	;	We have the New size, now we need to figure out where to store
	;	the New list.

			lda		WhichList
			jeq		makeNewList

			jmi		stretchSingle

	;	There is a full Range List and a short Single list.
	;	Now stretch the RangeDeps and insert the SingleDeps at the
	;	beginning of this dependency list.

			MoveLong	RangeDeps,NewDepList

			H_ResizeBlock	RangeDeps,NewDepSize,NewDepPtr,err=ErrorFlag
			jcs			Exit

	;	The range list is now big enough, we need to shift the
	;	range over to make room for the single deps.

			AddLong	NewDepPtr,#S_DependList,s
			AddLong	NewDepPtr,SingleDepSize,s
			SubLong	RangeDepSize,#S_DependList,s
			Tool		_BlockMove

			MoveWord	SingleDeps,[NewDepPtr]:#S_DependList

			lda		SingleDeps+2
			and		#$FFFF-S_CellTableFlags
			MoveWord	a,[NewDepPtr]:#S_DependList+2

			brl		fixDependHeader

	;	Neither of the lists is a full list.  Make one.

makeNewList
			H_NewBlock	NewDepSize,NewDepList,NewDepPtr,err=ErrorFlag
			jcs			Exit

			MoveWord	SingleDeps,[NewDepPtr]:#S_DependList

			lda		SingleDeps+2
			and		#$FFFF-S_CellTableFlags
			MoveWord	a,[NewDepPtr]:#S_DependList+2

			bra		insert1RangeDep

	;	The SingleDeps is a full list.
	;	So stretch the SingleDeps and insert the RangeDeps at the
	;	end of this dependency list.

stretchSingle
			MoveLong	SingleDeps,NewDepList

			H_ResizeBlock	SingleDeps,NewDepSize,NewDepPtr,err=ErrorFlag
			jcs			Exit

	;	We now have a block that already contains the single deps
	;	in the front part of the list.  Add the RangeDeps.

			lda		RangeDeps+2
			bpl		fullRangeDeps2

insert1RangeDep
			AddLong	NewDepPtr,SingleDepSize,RangeDepPtr

			MoveWord	RangeDeps,[RangeDepPtr]
			lda		RangeDeps+2
			and		#$FFFF-S_CellTableFlags
			MoveWord	a,[RangeDepPtr]:#2

			bra		fixDependHeader

fullRangeDeps2
			H_GetBlockPtr	RangeDeps,s

			AddLong	1:s,#S_DependList,1:s
			AddLong	NewDepPtr,SingleDepSize,s
			SubLong	RangeDepSize,#S_DependList,s
			Tool		_BlockMove,in=(:l,:l,:l)

			H_DisposeBlock	RangeDeps

	;	We need to fix the header information at the beginning
	;	of the NewDepList.

fixDependHeader
			MoveLong	NewDepSize,[NewDepPtr]
			MoveLong	SingleDepSize,[NewDepPtr]:#S_DependRangeList

			lda		NewDepList+2
			ora		#S_CellTableList
			sta		NewDepList+2

Exit
			RETURN
			ENDP

;----------------------------------------------------------------------------
;	S_TraverseDependFormulas
;
;	This routine will traverse a Source cell's dependency list and call one
; of two routines for every DependOnMe in the list. This first routine is
; for single cell references and the second is for ranges.
;
;	Call	SingleFunc,in=(DependCell:l,FormulaIndex:l)
;
;	Call	RangeFunc,in=(DependCell:l,FormulaIndex:l),out=(MovedBool:w)
;
;	This SingleFunc should not change the depend list. RangeFunc may,
; but must note this in the output. (1 = changed)
;


S_TraverseDependFormulas	PROC		EXPORT
					;Using	S_CurrentData

			input	SrcCell:l,SrcCellTableEntry:l,SingleFunc:l,RangeFunc:l
			local	SrcCellPtr:l,DependIndex:l
			local	DependPtr:l,Start:l,Stop:l
			local	DestCell:l,DestCellPtr:l,FormulaPtr:l
			local	Ptr:l,FakeSrcFlag:w
			error	ErrorFlag
			BEGIN

			stz		ErrorFlag

	;	First find out if the CellTableEntry is a Depend-list or a Cell Index

			lda		SrcCellTableEntry+2
			and		#S_CellTableFlags
			sta		FakeSrcFlag
			beq		doRealSrc1

			MoveLong	SrcCellTableEntry,DependIndex
			bra		chkDepIndex

doRealSrc1
			H_GetBlockPtr	SrcCellTableEntry,SrcCellPtr

			MoveLong	[SrcCellPtr]:#S_CellDependOnMe,DependIndex

chkDepIndex
			lda		DependIndex
			ora		DependIndex+2
			jeq		Exit


			MoveWord	SingleFunc,SingleCall+1
			sta		SingleCall2+1
			MoveWord	SingleFunc+1,SingleCall+2
			sta		SingleCall2+2

			MoveWord	RangeFunc,RangeCall+1
			sta		RangeCall2+1
			MoveWord	RangeFunc+1,RangeCall+2
			sta		RangeCall2+2


			lda		DependIndex+2
			bpl		fullList

	;	We have a short list.  This requires only one call to either the
	;	single or range function.

shortList
			MoveWord	DependIndex,DestCell
			lda		DependIndex+2
			and		#$FFFF-S_CellTableFlags
			sta		DestCell+2
			
			in		DestCell:l
			out		DestCellPtr:l
			XCall	S_GetCellPtr

			lda		DestCellPtr+2					; Whoops!  This needs to
			ora		DestCellPtr					; be here, since in the
			beq		goToExit						; move/swap of circular
												; formulas it is possible
			MoveWord	[DestCellPtr]:#S_CellFormat,a		; to imply that a cell exists
			bmi		goToExit						; with a ref. that is not
												; really there, or is only
			and		#S_CellTypeTextForm	;any formula	; a pad cell.  (I think the
			beq		goToExit						; last check, for formulas,
												; is not really necessary,
												; but I am including it for
												; completeness.) MRH 6/9/89

			lda		DependIndex+2
			and		#S_CellTableFlags
			cmp		#S_CellTableRangeDep
			bne		oneSingle

	;	One range function call

			SpaceWord
			PushLong	DestCell
			PushLong	[DestCellPtr]:#S_CellContent
RangeCall2	jsl		*
			sta		ErrorFlag
			pla

goToExit
			brl		Exit

	;	One single function call

oneSingle
			PushLong	DestCell
			PushLong	[DestCellPtr]:#S_CellContent
SingleCall2	jsl		*
			sta		ErrorFlag
			brl		Exit

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

	;	Adjust the cell's DependOnMe single references
	;	We know that the Depend-list is an index

fullList
			and		#$FFFF-S_CellTableFlags
			sta		DependIndex+2

			H_GetBlockPtr	DependIndex,DependPtr

			MoveLong	#S_DependList,Start
			MoveLong	[DependPtr]:#S_DependRangeList,Stop

			bra		cmpEnd

singleLoop
			AddLong	DependPtr,Start,Ptr
			MoveLong	[Ptr],DestCell

			in		DestCell:l
			out		DestCellPtr:l
			XCall	S_GetCellPtr

			lda		DestCellPtr+2					; See the above comment
			ora		DestCellPtr					; about similar code.
			beq		nextSingle					;
												;
			MoveWord	[DestCellPtr]:#S_CellFormat,a		;
			bmi		nextSingle					;
												;
			and		#S_CellTypeTextForm	;any formula	;
			beq		nextSingle					;

			PushLong	DestCell
			PushLong	[DestCellPtr]:#S_CellContent
SingleCall	jsl		*
			sta		ErrorFlag
			jcs		Exit

			H_GetBlockPtr	DependIndex,DependPtr	; We must Deref again, because
											; building Undo may move memory
											; The list is still the same.
nextSingle
			AddLong	Start,#4,Start

cmpEnd
			CmpLong	Start,Stop
			blt		singleLoop


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

	;	Adjust the cell's DependOnMe range references,
	;	We still know that the Depend-list is still an index,
	;	and that DependPtr is accurate.

			MoveLong	[DependPtr]:#S_DependRangeList,Start
			brl		cmpEnd2

rangeLoop
			AddLong	DependPtr,Start,Ptr
			MoveLong	[Ptr],DestCell

			in		DestCell:l
			out		DestCellPtr:l
			XCall	S_GetCellPtr

			lda		DestCellPtr+2					; See the above comments
			ora		DestCellPtr					; about similar code.
			beq		nextRange2					;
												;
			MoveWord	[DestCellPtr]:#S_CellFormat,a		;
			bmi		nextRange2					;
												;
			and		#S_CellTypeTextForm	;any formula	;
			beq		nextRange2					;

			SpaceWord
			PushLong	DestCell
			PushLong	[DestCellPtr]:#S_CellContent
RangeCall		jsl		*
			sta		ErrorFlag
			pla

			bcs		goToExit2
			bne		getListAgain

			H_GetBlockPtr	DependIndex,DependPtr

nextRange2
			AddLong	Start,#4,Start

cmpEnd2
			CmpLong	Start,[DependPtr]
			blt		rangeLoop

goToExit2
			bra		Exit

		;	The following code is for finding the dependency list again after
		;	it was changed in the RangeFunc.  Since we are only interested in
		;	range part of the list, we can not use the initialization code.

getListAgain
			lda		FakeSrcFlag
			beq		doRealSrc2

			in		SrcCell:l
			out		DependIndex:l
			XCall	S_GetCellTableEntry

			bra		gotDepList2

doRealSrc2
			H_GetBlockPtr	SrcCellTableEntry,SrcCellPtr
			MoveLong		[SrcCellPtr]:#S_CellDependOnMe,DependIndex

gotDepList2
			lda		DependIndex+2			; Is there a list left.
			ora		DependIndex
			beq		Exit

			lda		DependIndex+2			; check for short list
			bpl		fullList2

			and		#S_CellTableFlags
			cmp		#S_CellTableSingDep
			beq		Exit

			brl		shortList

	;	We know that the Dep list is still an index.

fullList2
			and		#$FFFF-S_CellTableFlags
			sta		DependIndex+2

			H_GetBlockPtr	DependIndex,DependPtr	; Since the Dep list changed
			bra			cmpEnd2				; we will do this location again.
							
Exit
			RETURN
			ENDP

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

S_FixDependList	PROC		EXPORT
				;Using	S_CurrentData
				;Using	S_MoveData

			input	Cell:l
			local	DependList:l,Stop:l,CellTableEntry:l
			local	FakeCellFlag:w,Flags:w
			error	ErrFlag
			BEGIN

CellPtr		equ		CellTableEntry
DependPtr		equ		DependList

			stz		ErrFlag

			in		Cell:l
			out		CellTableEntry:l
			XCall	S_GetCellTableEntry

			ora		CellTableEntry			; this can happen when
			jeq		Exit					; a cell refers to itself

			lda		CellTableEntry+2
			and		#S_CellTableFlags
			sta		FakeCellFlag
			beq		doRealCell

			MoveLong	CellTableEntry,DependList
			bra		chkDependList

doRealCell
			H_GetBlockPtr	CellTableEntry,CellPtr

			MoveLong	[CellPtr]:#S_CellDependOnMe,DependList

chkDependList
			lda		DependList+2
			bpl		fullList

	;	This is a short list.  If it points to the S_MoveOldCell,
	;	change it to the S_NewMoveCell.

			and		#S_CellTableFlags
			sta		Flags

			lda		DependList+2
			and		#$FFFF-S_CellTableFlags
			cmp		S_MoveOldCell+2
			bne		toExit

			CmpWord	DependList,S_MoveOldCell
			bne		toExit

			MoveWord	S_MoveNewCell,DependList
			lda		S_MoveNewCell+2
			ora		Flags
			sta		DependList+2

			lda		FakeCellFlag
			beq		realCell

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

toExit
			brl		Exit

realCell
			MoveLong	DependList,[CellPtr]:#S_CellDependOnMe
			bra		Exit

	;	This is a full list.  Change all occurances of the S_MoveOldCell
	;	to the S_MoveNewCell

fullList
			and		#$FFFF-S_CellTableFlags
			sta		DependList+2

			H_GetBlockPtr	DependList,DependPtr

;			lda		DependPtr+2
;			ora		DependPtr				; I dont know if this
;			beq		Exit					; ever happens

			AddLong	DependPtr,[DependPtr],Stop
			AddLong	DependPtr,#S_DependList,DependPtr

formLoop
			CmpLong	S_MoveOldCell,[DependPtr]
			bne		fixedToHere

			MoveLong	S_MoveNewCell,[DependPtr]

fixedToHere
			AddLong	DependPtr,#4,DependPtr

			CmpLong	DependPtr,Stop
			blt		formLoop

Exit
			RETURN
			ENDP

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

S_FixFormula	PROC		EXPORT
			;Using	S_CurrentData
			;Using	S_MoveData

			input	Cell:l,FormulaIndex:l
			local	FormulaPtr:l
			local	Start:w,Stop:w,RealCell:l
			local	RefByte:w
			error	ErrFlag
			BEGIN

	ProfileIn		4

			stz		ErrFlag

			H_GetBlockPtr	FormulaIndex,FormulaPtr

			MoveWord	[FormulaPtr]:#E_FormulaCells,Stop
			MoveWord	#E_FormulaData,Start

	;	No need to check first, a DependOnMe pointer assures at least
	;	one cell in formula

dependLoop
			MoveWord	[FormulaPtr]:Start,a
			and		#$0080
			jne		notSingleCell

			lda		[FormulaPtr],y				; this hack lets me
			and		#S_RecentlyChangedBit		; know if this is a
			jne		nextDepend				; newly changed reference

			SpaceLong
			AddWord	Start,#3,y
			PushWord	[FormulaPtr]:y
			dey
			dey
			PushWord	[FormulaPtr]:y
			dey
			lda		[FormulaPtr],y
			and		#$00FF
			sta		RefByte
			pha
			PushLong	Cell
			Call		S_GetRealCell
			PullLong	RealCell

			CmpLong	RealCell,S_MoveOldCell
			bne		nextDepend

			in		S_MoveNewCell:l,RefByte:w,Cell:l
			XCall	S_GetRefCell

			pla
			ora		S_FixFormulaFlag
			MoveWord	a,[FormulaPtr]:Start

			iny
			PullLong	[FormulaPtr]:y

nextDepend
			AddWord	Start,#5,Start
			bra		cmpEnd

notSingleCell
			AddWord	Start,#10,Start

cmpEnd
			CmpWord	Start,Stop
			jlt		dependLoop

	ProfileOut	4

			RETURN


				EXPORT	S_FixFormulaFlag
S_FixFormulaFlag	DC.W		0

	;	This purpose of this flag is so that swaps can know if	;
	;	the cell is a recently converted cell reference.		;

			ENDP

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

S_FixFormula2	PROC		EXPORT
			;Using	S_CurrentData
			;Using	S_MoveData
			;Using	S_DependData

			input	Cell:l,FormulaIndex:l
			output	Moved:w
			local	Start:w,Stop:w,RealCell:l,RealCell2:l
			local	RefByte:w,RefByte2:w,FormulaPtr:l,WhichEnd:w
			local	RecentChange1:w,RecentChange2:w
			local	NewRealCell:l,NewRealCell2:l
			error	ErrorFlag
			BEGIN

	ProfileIn		5

			stz		ErrorFlag
			stz		Moved

			H_GetBlockPtr	FormulaIndex,FormulaPtr

			MoveWord	[FormulaPtr]:#E_FormulaCells,Stop
			MoveWord	#E_FormulaData,Start

	;	No need to check first, a DependOnMe pointer assures at least
	;	one cell in formula

dependLoop
			stz		WhichEnd

			MoveWord	[FormulaPtr]:Start,a
			and		#$0080
			jeq		notRange

			lda		[FormulaPtr],y				; this hack lets me
			and		#S_RecentlyChangedBit		; know if this is a
			sta		RecentChange1				; newly changed reference

			SpaceLong
			AddWord	Start,#3,y
			PushWord	[FormulaPtr]:y
			dey
			dey
			PushWord	[FormulaPtr]:y
			dey
			lda		[FormulaPtr],y
			and		#$00FF
			sta		RefByte
			pha
			PushLong	Cell
			Call		S_GetRealCell
			PullLong	RealCell

			SpaceLong
			AddWord	Start,#8,y
			PushWord	[FormulaPtr]:y
			dey
			dey
			PushWord	[FormulaPtr]:y
			dey
			lda		[FormulaPtr],y
			and		#$00FF
			sta		RefByte2
			pha

			lda		[FormulaPtr],y				; this hack lets me
			and		#S_RecentlyChangedBit		; know if this is a
			sta		RecentChange2				; newly changed reference

			PushLong	Cell
			Call		S_GetRealCell
			PullLong	RealCell2

	;	Are any changes necessary	;

			CmpLong	RealCell,S_MoveOldCell
			bne		same1

			lda		RecentChange1
			bne		same1

			inc		WhichEnd
			MoveLong	S_MoveNewCell,NewRealCell
			bra		chk2

same1
			MoveLong	RealCell,NewRealCell

chk2
			CmpLong	RealCell2,S_MoveOldCell
			bne		same2

			lda		RecentChange2
			bne		same2

			lda		#2
			tsb		WhichEnd
			MoveLong	S_MoveNewCell,NewRealCell2
			bra		chkAny

same2
			MoveLong	RealCell2,NewRealCell2

chkAny
			lda		WhichEnd
			jeq		nextDepend

			MoveLong	Cell,S_DependHomeCell
			inc		Moved

			Call		S_NormalizeRange,in=(NewRealCell:l,NewRealCell2:l)

			in		#S_EnterRangeDep:l				; 2 inputs already on stack
			XCall	S_TraverseRange,err=ErrorFlag
			jcs		memError


			Call		S_NormalizeRange,in=(RealCell:l,RealCell2:l)

			in		#S_RemoveRangeDep:l				; 2 inputs already on stack
			XCall	S_TraverseRange,err=ErrorFlag

			H_GetBlockPtr	FormulaIndex,FormulaPtr

			lda		WhichEnd
			and		#1
			beq		fixSecond

			in		NewRealCell:l,RefByte:w,Cell:l
			XCall	S_GetRefCell

			pla
			ora		S_FixFormulaFlag
			MoveWord	a,[FormulaPtr]:Start

			iny
			PullLong	[FormulaPtr]:y

fixSecond
			lda		WhichEnd
			and		#2
			beq		nextDepend

			in		NewRealCell2:l,RefByte2:w,Cell:l
			XCall	S_GetRefCell

			AddWord	Start,#5,y
			pla
			ora		S_FixFormulaFlag
			sta		[FormulaPtr],y

			iny
			PullLong	[FormulaPtr]:y

nextDepend
			AddWord	Start,#10,Start
			bra		cmpEnd

notRange
			AddWord	Start,#5,Start

cmpEnd
			CmpWord	Start,Stop
			jlt		dependLoop

			lda		Moved
			beq		Exit

			Call		S_ResetCircularity,in=(Cell:l)
			Call		S_SetCircularBits,in=(Cell:l)
;			bra		Exit

memError
Exit

	ProfileOut	5

			RETURN
			ENDP

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

S_ChkContent	PROC		EXPORT
			;Using	S_CurrentData

			input	Cell:l,CellIndex:l
			local	CellPtr:l
			error	ErrorFlag
			BEGIN

			stz		ErrorFlag

			H_GetBlockPtr	CellIndex,CellPtr

			MoveWord	[CellPtr]:#S_CellFormat,a
			bmi		Exit

			inc		ErrorFlag

Exit
			RETURN
			ENDP
			END

