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

1 line
42 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 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