antoine-source/appleworksgs/SS/Src/Cells2.aii
2023-03-04 03:45:20 +01:00

1 line
26 KiB
Plaintext
Executable File

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