
		LOAD		'Macros.dump'

		INCLUDE	'SS.equ'

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

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

		IMPORT	D_FastMult

		IMPORT	S_CellWidth
		IMPORT	S_ColLab2Text
		IMPORT	S_QTraverseTable

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

		ENTRY	S_InRange

;-------------------------------------------------------------------------
;	S_AdjustCell
;

S_AdjustCell	PROC		EXPORT

			output	Cell:l,Xpt:w,Ypt:w			; these are both input
			BEGIN							; and output

			CmpWord	Cell,#10000
			blt		OK1

			MoveWord	#9999,Cell
			SubWord	Ypt,#S_RowHeight,Ypt

OK1
			CmpWord	Cell+2,#$02BF
			blt		OK2

			MoveWord	#$02BE,Cell+2

			Call		S_CellWidth,in=(Cell+2:w),out=(:w)
			SubWord	Xpt,s,Xpt

OK2
			RETURN
			ENDP

;---------------------------------------------------------------------------
;	S_AdjustPoint
;

S_AdjustPoint	PROC		EXPORT

			output	Xpt:w,Ypt:w
			BEGIN

			lda		Ypt
			bpl		OKy

			stz		Ypt

OKy
			lda		Xpt
			bpl		Exit

			stz		Xpt

Exit
			RETURN
			ENDP

;---------------------------------------------------------------------------
;
; S_Cell2Str	
;

S_Cell2Str	PROC		EXPORT

			input	ptr:l,cell:l
			local	offset:w,length:w
			begin

			moveword	#0,[ptr]

			moveword	#1,offset
			rcall	S_ColLab2Text,in=(cell+2:a),out=([ptr]:#1:a)

			and		#$00FF
			cmp		#$0020				; space
			bne		Cont1

			dec		offset

			lda		[ptr],y
			xba
			sta		[ptr],y

Cont1
			inc		offset
			inc		offset
			moveword	#1,length
			cmpw		cell,#10
			blt		GotLength

			inc		length
			cmp		#100
			blt		GotLength

			inc		length
			cmp		#1000
			blt		GotLength

			inc		length

GotLength		pushword	cell
			lda		offset
			addlong	a,ptr,s
			pushword	length
			pushword	#0
			_Int2Dec

			addword	length,offset,a
			dec		a

			ora		[ptr]
			sta		[ptr]

			return
			ENDP

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

S_DisposeRowBlock	PROC		EXPORT

			input	RowBlock:l
			local	RowPtr:l,RowOffset:w,RowHandle:l
			BEGIN

			lda		RowBlock
			ora		RowBlock+2
			beq		Exit

			MoveLong	[RowBlock],RowPtr

			SubWord	[RowPtr]:#S_KeyMax,[RowPtr]:#S_KeyMin,a
			asl		a
			asl		a
			AddWord	a,#S_KeyArray,RowOffset

loop
			SubWord	RowOffset,#4,RowOffset
			cmp		#S_KeyArray
			blt		killRowBlock

			tay
			MoveLong	[RowPtr]:y,RowHandle

			ora		RowHandle
			beq		loop

			Tool		_DisposeHandle,in=(RowHandle:l)
			bra		loop

killRowBlock
			Tool		_DisposeHandle,in=(RowBlock:l)

Exit
			RETURN
			ENDP

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

S_GetDestCellRanges	PROC		EXPORT

			input	OrigTL:l,OrigBR:l,DestTL:l,DestBR:l
			output	Range1TL:l,Range1BR:l,Range2TL:l,Range2BR:l

			local	JumpIndex:w
			BEGIN


DestTop		equ		DestTL
DestLeft		equ		DestTL+2
DestBottom	equ		DestBR
DestRight		equ		DestBR+2

Range1Top		equ		Range1TL
Range1Left	equ		Range1TL+2
Range1Bottom	equ		Range1BR
Range1Right	equ		Range1BR+2

Range2Top		equ		Range2TL
Range2Left	equ		Range2TL+2
Range2Bottom	equ		Range2BR
Range2Right	equ		Range2BR+2

			stz		JumpIndex
			stzl		Range1TL
			stzl		Range1BR
			stzl		Range2TL
			stzl		Range2BR

			in		OrigTL:l,OrigBR:l,DestLeft:w,DestTop:w
			out		a:w
			XCall	S_InRange

			beq		OK1

			lda		#2
			tsb		JumpIndex
OK1

			in		OrigTL:l,OrigBR:l,DestRight:w,DestBottom:w
			out		a:w
			XCall	S_InRange

			beq		OK2

			lda		#4
			tsb		JumpIndex
OK2

			in		OrigTL:l,OrigBR:l,DestRight:w,DestTop:w
			out		a:w
			XCall	S_InRange

			beq		OK3

			lda		#8
			tsb		JumpIndex
OK3

			in		OrigTL:l,OrigBR:l,DestLeft:w,DestBottom:w
			out		a:w
			XCall	S_InRange

			beq		OK4

			lda		#16
			tsb		JumpIndex
OK4

			ldx		JumpIndex
			jmp		(JumpTable,x)


Index4
			MoveWord	OrigTL,Range2Top
			MoveWord	DestLeft,Range2Left

			MoveWord	DestBottom,Range2Bottom
			lda		OrigTL+2
			dec		a
			sta		Range2Right

Index20
			MoveWord	DestTop,Range1Top
			MoveWord	DestLeft,Range1Left

			lda		OrigTL
			dec		a
			sta		Range1Bottom
			MoveWord	DestRight,Range1Right

			brl		Exit

Index16
			MoveWord	DestTop,Range2Top
			MoveWord	DestLeft,Range2Left

			lda		OrigTL
			dec		a
			sta		Range2Bottom
			MoveWord	DestRight,Range2Right

Index18
			MoveWord	OrigTL,Range1Top
			lda		OrigBR+2
			inc		a
			sta		Range1Left

			MoveWord	DestBottom,Range1Bottom
			MoveWord	DestRight,Range1Right

			brl		Exit

Index2
			MoveWord	DestTop,Range2Top
			lda		OrigBR+2
			inc		a
			sta		Range2Left

			MoveWord	DestBottom,Range1Bottom
			MoveWord	DestRight,Range1Right

Index10
			lda		OrigBR
			inc		a
			sta		Range1Top
			MoveWord	DestLeft,Range1Left

			MoveWord	DestBottom,Range1Bottom
			MoveWord	DestRight,Range1Right

			brl		Exit

Index8
			lda		OrigBR
			inc		a
			sta		Range2Top
			MoveWord	DestLeft,Range2Left

			MoveWord	DestBottom,Range2Bottom
			MoveWord	DestRight,Range2Right

Index12
			MoveWord	DestTop,Range1Top
			MoveWord	DestLeft,Range1Left

			MoveWord	DestBottom,Range1Bottom
			lda		OrigTL+2
			dec		a
			sta		Range1Right

			bra		Exit

Index0
			MoveWord	DestTop,Range1Top
			MoveWord	DestLeft,Range1Left

			MoveWord	DestBottom,Range1Bottom
			MoveWord	DestRight,Range1Right

ErrorIndex
Exit
			RETURN

JumpTable
			DC.W		Index0		; The corner assignments are
			DC.W		Index2
			DC.W		Index4		;	-------------
			DC.W		ErrorIndex	;	| 2		8 |
			DC.W		Index8		;	|		  |
			DC.W		Index10		;	|		  |
			DC.W		Index12		;	|		  |
			DC.W		ErrorIndex	;	| 16		4 |
			DC.W		Index16		;	-------------
			DC.W		Index18
			DC.W		Index20		; This is the destination region
			DC.W		ErrorIndex
			DC.W		ErrorIndex
			DC.W		ErrorIndex
			DC.W		ErrorIndex
			DC.W		Exit			; dest equals src

			ENDP

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

S_GetRealCell	PROC		EXPORT

			input	RefCell:l,RefByte:w,CallingCell:l
			output	RealCell:l
			BEGIN

			CmpLong	RefCell,#S_NotACell
			bne		isACell
			MoveLong	RefCell,RealCell
			brl		Exit

isACell
			MoveWord	RefCell,RealCell			; set row

			lda		RefByte
			and		#$0003
			beq		doNegRow

			cmp		#2
			bge		getCol

			AddWord	CallingCell,RealCell,RealCell
			bra		getCol

doNegRow
			SubWord	CallingCell,RealCell,RealCell

getCol										; set col
			MoveWord	RefCell+2,RealCell+2

			lda		RefByte
			and		#$000C
			beq		doNegCol

			cmp		#8
			bge		Exit

			AddWord	CallingCell+2,RealCell+2,RealCell+2
			bra		Exit

doNegCol
			SubWord	CallingCell+2,RealCell+2,RealCell+2

Exit
			RETURN
			ENDP

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

S_GetRefCell	PROC		EXPORT

			input	CallingCell:l
			output	RefCell:l,RefByte:w	; in/out parms
			BEGIN

			CmpLong	RefCell,#S_NotACell
			beq		Exit

	;	Adjust Row and Col for relative references, if necessary	;

			lda		RefByte
			and		#E_RefAbsAbs+$0080
			sta		RefByte

			and		#E_RefAbsNeg
			bne		ColOK

			CmpWord	CallingCell+2,RefCell+2
			blt		posCol

			SubWord	a,RefCell+2,RefCell+2
			bra		ColOK

posCol
			SubWord	RefCell+2,CallingCell+2,RefCell+2
			lda		#E_RefPosNeg
			ora		RefByte
			sta		RefByte

ColOK
			lda		RefByte
			and		#E_RefNegAbs
			bne		RowOK

			CmpWord	CallingCell,RefCell
			blt		posRow

			SubWord	a,RefCell,RefCell
			bra		RowOK

posRow
			SubWord	RefCell,CallingCell,RefCell
			lda		#E_RefNegPos
			ora		RefByte
			sta		RefByte

RowOK
Exit
			RETURN
			ENDP

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

S_InRange		PROC		EXPORT

			input	Cell1:l,Cell2:l,TestCell:l
			output	Answer:w
			BEGIN

			stz		Answer

			lda		TestCell

			cmp		Cell1
			blt		chkGERow2
			beq		OKRow

			cmp		Cell2
			blt		OKRow
			beq		OKRow
			bra		Exit

chkGERow2
			cmp		Cell2
			blt		Exit

OKRow
			lda		TestCell+2

			cmp		Cell1+2
			blt		chkGECol2
			beq		OKCol

			cmp		Cell2+2
			blt		OKCol
			beq		OKCol
			bra		Exit

chkGECol2
			cmp		Cell2+2
			blt		Exit

OKCol
			inc		Answer

Exit
			RETURN
			ENDP

;-----------------------------------------------------------------------------
; S_NormalizeRange ( TLCell:l,BRCell:l )
;
;	These are input/output parameters!

S_NormalizeRange	PROC		EXPORT

			output	TLCell:l,BRCell:l
			BEGIN

			CmpWord	TLCell+2,BRCell+2			; compare the cols only
			blt		doTop

			ldy		BRCell+2
			sty		TLCell+2
			sta		BRCell+2

doTop
			CmpWord	TLCell,BRCell				; compare the rows only
			blt		Exit

			ldy		BRCell
			sty		TLCell
			sta		BRCell

Exit
			RETURN
			ENDP

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

S_SectRange	PROC		EXPORT

			input	Range1Ptr:l,Range2Ptr:l,SectRangePtr:l
			output	RangeValid:w
			BEGIN

			MoveWord	#1,RangeValid

	;	Find Top	;

			CmpWord	[Range1Ptr],[Range2Ptr]
			bge		setTop

			lda		[Range2Ptr]

setTop
			sta		[SectRangePtr]

	;	Find Left ;

			ldy		#2
			CmpWord	[Range1Ptr]:y,[Range2Ptr]:y
			bge		setLeft

			lda		[Range2Ptr],y

setLeft
			sta		[SectRangePtr],y

	;	Find Bottom	;

			ldy		#4
			CmpWord	[Range1Ptr]:y,[Range2Ptr]:y
			blt		setBottom

			lda		[Range2Ptr],y

setBottom
			sta		[SectRangePtr],y

	;	Find Right	;

			ldy		#6
			CmpWord	[Range1Ptr]:y,[Range2Ptr]:y
			blt		setRight

			lda		[Range2Ptr],y

setRight
			sta		[SectRangePtr],y

	;	Compare if valid range	;

			lda		[SectRangePtr],y
			ldy		#2
			cmp		[SectRangePtr],y
			bge		ColOK

			lda		#0
			sta		RangeValid
			sta		[SectRangePtr],y
			ldy		#6
			sta		[SectRangePtr],y

ColOK
			ldy		#4
			lda		[SectRangePtr],y
			cmp		[SectRangePtr]
			bge		Exit

			lda		#0
			sta		RangeValid
			sta		[SectRangePtr],y
			sta		[SectRangePtr]

Exit
			RETURN
			ENDP

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

S_Text2Cell	PROC		EXPORT

			input	TextPtr:l,Size:w
			output	CellID:l
			local	Len:w,Index:w,LLimit:w
			error	ErrorFlag
			BEGIN

			stz		ErrorFlag

	;	Get Column	;

			ldy		#0
			stz		Len
			short

colLoop
			cpy		Size
			bge		doneColLoop

			lda		[TextPtr],y
			cmp		#$41					; hex for 'A'
			blt		doneColLoop
			and		#$DF					; make Upper case
			cmp		#$5B					; hex for ('Z' + 1)
			bge		doneColLoop

			sta		[TextPtr],y

			iny
			inc		Len
			bra		colLoop

doneColLoop

			long

			sty		Index
			stz		CellID+2

	;	Check if it can be cell	;

			lda		Len
			jeq		noGood

			cmp		#3					; no cell col is 3 long
			bge		noGood
			cmp		#2
			beq		twoChars

			lda		[TextPtr]
			and		#$00FF
			SubWord	a,#$0040,a			; hex for 'A' - 1 = '@'
			bra		oneChar

twoChars
			SubWord	[TextPtr],#$4040,a		; hex for '@@'

			pha

			and		#$00FF
			tax
			ldy		#26
			Call		D_FastMult
			sta		CellID+2

			pla
			xba
			and		#$00FF

oneChar
			AddWord	a,CellID+2,CellID+2

	;	Get Row	;

			ldy		Index
			stz		Len

			short
			MoveWord	#'1',LLimit

rowLoop
			cpy		Size
			bge		doneRowLoop

			lda		[TextPtr],y
			cmp		LLimit				; hex for 'A'
			blt		doneRowLoop
			cmp		#'9'+1
			bge		doneRowLoop

			iny
			inc		Len
			MoveWord	#'0',LLimit
			bra		RowLoop

doneRowLoop

			long

			stz		CellID
			lda		Len
			beq		noGood
			cmp		#5					; no cell row is 5 long
			bge		noGood

nextDigit
			ldy		Index
			inc		Index
			cpy		Size
			bge		Exit

			lda		[TextPtr],y
			and		#$00FF
			SubWord	a,#$0030,s
			ldx		CellID
			ldy		#10
			Call		D_FastMult
			AddWord	a,s,CellID
			bra		nextDigit

noGood
			inc		ErrorFlag
			stz		CellID
			stz		CellID+2

Exit
			RETURN
			ENDP

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

S_TraverseDest	PROC		EXPORT

			input	OrigTL:l,OrigBR:l,DestTL:l,DestBR:l,Routine:l
			local	Range1TL:l,Range1BR:l,Range2TL:l,Range2BR:l
			error	ErrorFlag
			BEGIN

			stz		ErrorFlag

			in		OrigTL:l,OrigBR:l
			in		DestTL:l,DestBR:l
			out		Range1TL:l,Range1BR:l,Range2TL:l,Range2BR:l
			XCall	S_GetDestCellRanges

			lda		Range2TL
			ora		Range2TL+2
			ora		Range2BR
			ora		Range2BR+2
			beq		doRange1

			in		Range2TL:l,Range2BR:l,Routine:l
			XCall	S_QTraverseTable,err=ErrorFlag

			bcs		Exit

doRange1
			lda		Range1TL
			ora		Range1TL+2
			ora		Range1BR
			ora		Range1BR+2
			beq		Exit

			in		Range1TL:l,Range1BR:l,Routine:l
			XCall	S_QTraverseTable,err=ErrorFlag

Exit
			RETURN
			ENDP
			END

