
		LOAD		'Macros.dump'

		INCLUDE	'SS.equ'

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

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

		IMPORT	D_GrowHandle
		IMPORT	D_NeedHand

		IMPORT	S_CurRowBlock

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

		ENTRY	S_GetKeyIndex
		ENTRY	S_GetRowStructIndex
		ENTRY	S_SetKeyIndex
		ENTRY	S_SetRowStructIndex

;---------------------------------------------------------------------------
;	S_SetCellTableEntry
;

S_SetCellTableEntry	PROC		EXPORT
				;Using	S_CurrentData

			input	Cell:l,NewCellIndex:l
			local	OldRowIndex:l,NewRowIndex:l
			error	ErrorFlag
			BEGIN

			stz		ErrorFlag

			in		Cell:w
			out		OldRowIndex:l
			XCall	S_GetRowStructIndex

			in		Cell+2:w,OldRowIndex:l,NewCellIndex:l
			out		NewRowIndex:l
			XCall	S_SetKeyIndex,err=ErrorFlag
			bcs		Exit

			CmpLong	OldRowIndex,NewRowIndex
			beq		Exit

			in		Cell:w,NewRowIndex:l
			XCall	S_SetRowStructIndex,err=ErrorFlag
			bcs		killNewRow

			lda		OldRowIndex
			ora		OldRowIndex+2
			beq		Exit

			Tool		_DisposeHandle,in=(OldRowIndex:l)
			bra		Exit

killNewRow
			Tool		_DisposeHandle,in=(NewRowIndex:l)

Exit
			RETURN
			ENDP

;---------------------------------------------------------------------------
;	S_GetCellTableEntry( Cell:l ) : Index:l
;

S_GetCellTableEntry	PROC		EXPORT
				;Using	S_CurrentData

			input	Cell:l
			output	Index:l
			BEGIN

StructPtr 	equ 		Index

			in		Cell:w
			out		StructPtr:l
			XCall	S_GetRowStructIndex

			ora		StructPtr
			beq		Exit

			in		Cell+2:w,StructPtr:l
			out		Index:l
			XCall	S_GetKeyIndex

Exit
			RETURN
			ENDP

;---------------------------------------------------------------------------
;	S_GetCellIndex( Cell:l ) : CellIndex:l
;

S_GetCellIndex	PROC		EXPORT
			;Using	S_CurrentData

			input	Cell:l
			output	CellIndex:l
			BEGIN

			Call		S_GetCellTableEntry,in=(Cell:l),out=(CellIndex:l)

			and		#S_CellTableFlags
			beq		Exit

			stzl		CellIndex

Exit
			RETURN
			ENDP

;---------------------------------------------------------------------------
;	S_GetCellPtr( Cell:l ) : CellPtr:l
;

S_GetCellPtr	PROC		EXPORT
			;Using	S_CurrentData

			input	Cell:l
			output	CellPtr:l
			BEGIN	+b

CellIndex		equ		CellPtr

			in		Cell:l
			out		CellIndex:l
			XCall	S_GetCellIndex

			ora		CellIndex
			beq		Exit					; return 0 if cell doesn't exist

			H_GetBlockPtr	CellIndex,CellPtr

Exit
			RETURN
			ENDP

;---------------------------------------------------------------------------
;	S_GetKeyIndex( Key:w,Struct:l ) : Index:l
;

S_GetKeyIndex	PROC		EXPORT
			;Using	S_CurrentData

			input	Key:w,Struct:l
			output	Index:l
			BEGIN

StructPtr	equ	Struct

;			MoveLong	[Struct],ax
			ldy		#2
			lda		[Struct],y
			tax
			lda		[Struct]
			sta		StructPtr
			stx		StructPtr+2

			CmpWord	Key,[StructPtr]:#S_KeyMax
			bge		notFound

			SubWord	a,[StructPtr]:#S_KeyMin,a
			blt		notFound

			asl		a
			asl		a
			AddWord	a,#S_KeyArray,y

			MoveLong	[StructPtr]:y,Index
			bra		Exit

notFound
			stz		Index
			stz		Index+2

Exit
			RETURN
			ENDP

;---------------------------------------------------------------------------
;	S_SetKeyIndex
;

S_SetKeyIndex	PROC		EXPORT
			;Using	S_CurrentData

			input	Key:w,OldStructIndex:l,NewIndex:l
			output	StructIndex:l

			local	StructPtr:l,Min:w,Max:w,ZeroMin:w,ZeroMax:w
			local	NewSize:w
			error	ErrorFlag
			BEGIN

S_Key2StructDefault	equ	26

			stz		ErrorFlag

			MoveWord	OldStructIndex,StructIndex
			MoveWord	OldStructIndex+2,StructIndex+2

			ora		OldStructIndex
			jne		structExists

			lda		NewIndex
			ora		NewIndex+2
			jeq		Exit

			in		#S_Key2StructDefault:l
			out		StructIndex:l
			XCall	D_NeedHand,err=ErrorFlag
			jcs		Exit

			MoveLong	[StructIndex],StructPtr

			MoveWord	#S_Key2StructDefault,[StructPtr]
			MoveWord	Key,[StructPtr]:#S_KeyMin
			inc		a
			MoveWord	a,[StructPtr]:#S_KeyMax
			MoveLong	NewIndex,[StructPtr]:#S_KeyArray
			brl		Exit

structExists
			MoveLong	[OldStructIndex],StructPtr

			CmpWord	Key,[StructPtr]:#S_KeyMax
			bge		notFoundMax

			SubWord	a,[StructPtr]:#S_KeyMin,a
			blt		notFoundMin

			asl		a
			asl		a
			AddWord	a,#S_KeyArray,y

	;	Put the New index over the last one, it is up to the caller
	;	to dispose of the old one.

			MoveLong	NewIndex,[StructPtr]:y
			brl		Exit

notFoundMax
			ldy		#S_KeyMin
			MoveWord	[StructPtr]:y,Min

			lda		Key
			inc		a
			sta		Max

			SubWord	a,[StructPtr]:y,a
			asl		a
			asl		a
			AddWord	a,#S_KeyArray,ZeroMax

			SubWord	[StructPtr]:#S_KeyMax,[StructPtr]:#S_KeyMin,a
			asl		a
			asl		a
			AddWord	a,#S_KeyArray,ZeroMin
			bra		loadIndex

notFoundMin
			eor		#$FFFF
			inc		a
			asl		a
			asl		a
			AddWord	a,#S_KeyArray,ZeroMax

			MoveWord	#S_KeyArray,ZeroMin

			MoveWord	Key,Min
			MoveWord	[StructPtr]:#S_KeyMax,Max

loadIndex
			lda		NewIndex
			ora		NewIndex+2
			jeq		Exit

			SubWord	Max,Min,a
			asl		a
			asl		a
			AddWord	a,#S_KeyArray,a
			cmp		[StructPtr]
			blt		OKsize

			AddWord	a,#S_Key2StructDefault,NewSize

			in		#0:w,NewSize:w,OldStructIndex:l
			XCall	D_GrowHandle,err=ErrorFlag
			bcs		Exit

			MoveLong	[OldStructIndex],StructPtr
			MoveWord	NewSize,[StructPtr]

OKsize
			CmpWord	ZeroMin,#S_KeyArray
			bne		OKfix

			AddLong	a,StructPtr,s
			lda		ZeroMax
			AddLong	a,StructPtr,s
			pea		0
			SubWord	[StructPtr]:#S_KeyMax,[StructPtr]:#S_KeyMin,a
			asl		a
			asl		a
			pha
			Tool		_BlockMove,in=(:l,:l,:l)

OKfix
			lda		#0
			ldy		ZeroMin

zeroLoop
			sta		[StructPtr],y
			iny
			iny
			cpy		ZeroMax
			blt		zeroLoop

			MoveWord	Min,[StructPtr]:#S_KeyMin
			MoveWord	Max,[StructPtr]:#S_KeyMax

			SubWord	Key,Min,a
			asl		a
			asl		a
			AddWord	a,#S_KeyArray,y
			MoveLong	NewIndex,[StructPtr]:y

Exit
			RETURN
			ENDP

;--------------------------------------------------------------------------
;	S_GetRowStructIndex( Row:w ) Index:l
;

S_GetRowStructIndex	PROC		EXPORT
				;Using	S_CurrentData

			input	Row:w
			output	StructIndex:l
			BEGIN

			stz		StructIndex
			stz		StructIndex+2

			lda		S_CurRowBlock
			ora		S_CurRowBlock+2
			beq		Exit

			in		Row:w,S_CurRowBlock:l
			out		StructIndex:l
			XCall	S_GetKeyIndex

Exit
			RETURN
			ENDP

;--------------------------------------------------------------------------
;	S_SetRowStructIndex( Row:w,Index:l )
;

S_SetRowStructIndex	PROC		EXPORT
				;Using	S_CurrentData

			input	Row:w,RowIndex:l
			local	NewRowBlock:l
			error	ErrorFlag
			BEGIN

			stz		ErrorFlag

			in		Row:w,S_CurRowBlock:l,RowIndex:l
			out		NewRowBlock:l
			XCall	S_SetKeyIndex,err=ErrorFlag
			bcs		Exit

			CmpLong	S_CurRowBlock,NewRowBlock
			beq		Exit

			lda		S_CurRowBlock
			ora		S_CurRowBlock+2
			beq		oldGone

			Tool		_DisposeHandle,in=(S_CurRowBlock:l)

oldGone
			MoveLong	NewRowBlock,S_CurRowBlock

Exit
			RETURN
			ENDP
			END

