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

1 line
11 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_AcceptCell
IMPORT S_AddCellToChangedList
IMPORT S_BuildTrashUndo
IMPORT S_DeltaMove
IMPORT S_DependHomeCell
IMPORT S_FixDependList
IMPORT S_GetCellTableEntry
IMPORT S_GetRealCell
IMPORT S_GetRefCell
IMPORT S_InRange
IMPORT S_MoveCell
IMPORT S_MoveDestBR
IMPORT S_MoveDestTL
IMPORT S_MoveOldCell
IMPORT S_MoveSrcTL
IMPORT S_NormalizeRange
IMPORT S_OrigTransDestBR
IMPORT S_OrigTransDestTL
IMPORT S_RemoveRangeDep
IMPORT S_ResetCircularity
IMPORT S_SetCellTableEntry
IMPORT S_SetCircularBits
IMPORT S_SplitDependList
IMPORT S_SwapCell
IMPORT S_TraverseDependFormulas
IMPORT S_TraverseRange
;-----------------------------------------------
;
; Forward addresses and entries
;
;-----------------------------------------------
ENTRY S_TrashFormula
ENTRY S_TrashFormula2
;-------------------------------------------------------------------------
;
;
S_TrashCell PROC EXPORT
;Using S_CurrentData
;Using S_MoveData
input Cell:l,CellTableEntry:l
local DependList:l,DependPtr:l
local CellPtr:l,FakeCellFlag:w
local SingleList:l,RangeList:l
local RangeStart:l,RangeSize:l
error ErrFlag
BEGIN
ProfileIn 1
stz ErrFlag
; We know that there is something at this location. If it is only
; a depend list, we can skip the first part of this routine.
lda CellTableEntry+2
and #S_CellTableFlags
sta FakeCellFlag
bne doTrashTraverse
; If a user-cell exists, we will first remove the cell (as if with
; a delete key). This will clean up any depend ptrs to this cell as
; well as fix up any pad cells.
ldx #S_CellTypeEmpty
in Cell:l,x:w,x:w,x:w,x:w
out :l,:l
XCall S_AcceptCell,err=ErrFlag
pla
plx
cpx S_MoveDestBR+2
blt chkLeft1
stx S_MoveDestBR+2
chkLeft1
pla
plx
cpx S_MoveDestTL+2
bge getIndex
stx S_MoveDestTL+2
getIndex
lda ErrFlag
jne Exit
; Now if there are any depend ptrs left at this location, we need to
; 'trash' the formulas that refer to this cell. First get the depend list.
;
Call S_GetCellTableEntry,in=(Cell:l),out=(CellTableEntry:l)
ora CellTableEntry
jeq Exit
lda CellTableEntry+2
and #S_CellTableFlags
sta FakeCellFlag
; This will traverse the depend list and trash any cells that refer
; to this cell.
doTrashTraverse
MoveLong Cell,S_MoveOldCell
in Cell:l,CellTableEntry:l,#S_TrashFormula:l,#S_TrashFormula2:l
XCall S_TraverseDependFormulas,err=ErrFlag
jcs Exit
; Get the DependList again. It could have changed, because trashing an
; endpt of a range will modify depend lists.
lda FakeCellFlag
beq doRealCell
Call S_GetCellTableEntry,in=(Cell:l),out=(DependList:l)
bra gotDepList
doRealCell
H_GetBlockPtr CellTableEntry,CellPtr
MoveWord [CellPtr]:#S_CellDependOnMe,DependList
MoveWord [CellPtr]:#S_CellDependOnMe+2,DependList+2
; If nothing left, quit.
gotDepList
ora DependList
bne gotDepList2
bra Exit
; Else, keep only the range part of the list. To do this we need
; to split up the list and Save the range part at the cell. We'll
; throw away the single part.
gotDepList2
in DependList:l
out SingleList:l,RangeList:l
XCall S_SplitDependList,err=ErrFlag
bcs Exit
; Save the range part.
lda FakeCellFlag
beq doPadCell2
Call S_SetCellTableEntry,in=(Cell:l,RangeList:l)
bra depListSet
doPadCell2
H_GetBlockPtr CellTableEntry,CellPtr
MoveWord RangeList,[CellPtr]:#S_CellDependOnMe
MoveWord RangeList+2,[CellPtr]:#S_CellDependOnMe+2
; Throw away the single part.
depListSet
lda SingleList+2
bmi Exit
and #$FFFF-S_CellTableFlags
sta SingleList+2
ora SingleList
beq Exit
H_DisposeBlock SingleList
Exit
ProfileOut 1
RETURN
ENDP
;----------------------------------------------------------------------------
;
;
S_TrashFormula PROC EXPORT
;Using S_CurrentData
;Using S_MoveData
input DependCell:l,FormulaIndex:l
local FormulaPtr:l,Start:w,Stop:w,RealCell:l
error ErrFlag
BEGIN
stz ErrFlag
Call S_AddCellToChangedList,in=(DependCell:l)
in DependCell:l,FormulaIndex:l
XCall S_BuildTrashUndo,err=ErrFlag
jcs Exit
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
SpaceLong
AddWord Start,#3,y
PushWord [FormulaPtr]:y
dey
dey
PushWord [FormulaPtr]:y
dey
lda [FormulaPtr],y
and #$00FF
pha
PushLong DependCell
Call S_GetRealCell
PullLong RealCell
CmpLong RealCell,S_MoveOldCell
bne nextDepend
ldy Start
iny
MoveLong #S_NotACell,[FormulaPtr]:y
nextDepend
AddWord Start,#5,Start
bra cmpEnd
notSingleCell
AddWord Start,#10,Start
cmpEnd
CmpWord Start,Stop
jlt dependLoop
Exit
RETURN
ENDP
;----------------------------------------------------------------------------
;
;
S_TrashFormula2 PROC EXPORT
;Using S_CurrentData
;Using S_MoveData
;Using S_DependData
input DependCell:l,FormulaIndex:l
output Moved:w
local FormulaPtr:l,Stop:w,Start:w
local RealCell:l,RealCell2:l,WhichEnd:w
error ErrFlag
BEGIN
stz ErrFlag
stz Moved
Call S_AddCellToChangedList,in=(DependCell:l)
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
jeq notRange
SpaceLong
AddWord Start,#3,y
PushWord [FormulaPtr]:y
dey
dey
PushWord [FormulaPtr]:y
dey
lda [FormulaPtr],y
and #$00FF
pha
PushLong DependCell
Call S_GetRealCell
PullLong RealCell
SpaceLong
AddWord Start,#8,y
PushWord [FormulaPtr]:y
dey
dey
PushWord [FormulaPtr]:y
dey
lda [FormulaPtr],y
and #$00FF
pha
PushLong DependCell
Call S_GetRealCell
PullLong RealCell2
CmpLong RealCell,S_MoveOldCell
beq doAdjust1
CmpLong RealCell2,S_MoveOldCell
jne nextDepend
MoveWord #1,WhichEnd
bra doAdjust
doAdjust1
stz WhichEnd
doAdjust
MoveLong DependCell,S_DependHomeCell
Call S_NormalizeRange,in=(RealCell:l,RealCell2:l)
in #S_RemoveRangeDep:l ; 2 inputs already on stack
XCall S_TraverseRange
in DependCell:l,FormulaIndex:l
XCall S_BuildTrashUndo,err=ErrFlag
bcs Exit
H_GetBlockPtr FormulaIndex,FormulaPtr
lda WhichEnd
bne doSecond
ldy Start
iny
bra fixRange
doSecond
AddWord Start,#6,y
fixRange
MoveLong #S_NotACell,[FormulaPtr]:y
inc Moved
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=(DependCell:l)
Call S_SetCircularBits,in=(DependCell:l)
Exit
RETURN
ENDP
;-------------------------------------------------------------------------
;
;
S_TransposeCell PROC EXPORT
;Using S_MoveData
input SrcCell:l
local DestCell:l,SrcIndex:l
error ErrorFlag
BEGIN
stz ErrorFlag
SubWord SrcCell+2,S_MoveSrcTL+2,a
AddWord a,S_MoveSrcTL,DestCell
SubWord SrcCell,S_MoveSrcTL,a
AddWord a,S_MoveSrcTL+2,DestCell+2
SubWord DestCell,SrcCell,S_DeltaMove
SubWord DestCell+2,SrcCell+2,S_DeltaMove+2
in S_OrigTransDestTL:l,S_OrigTransDestBR:l,SrcCell:l
out a:w
XCall S_InRange
beq notInRange
lda S_DeltaMove+2 ; note: during a transpose
bpl Exit ; only one direction is +
Call S_SwapCell,in=(SrcCell:l),err=ErrorFlag
bra Exit
notInRange
in SrcCell:l
out SrcIndex:l
XCall S_GetCellTableEntry
ora SrcIndex
beq Exit
in SrcCell:l,SrcIndex:l
XCall S_MoveCell
Exit
RETURN
ENDP
;-------------------------------------------------------------------------
;
;
S_FixFormula3 PROC EXPORT
;Using S_CurrentData
input SrcCell:l,DestCell:l,FormulaIndex:l
local FormulaPtr:l,Start:w,Stop:w,ChangedBit:w
local RefByte:w,RealCell:l,RealCell2:l
BEGIN
ProfileIn 6
H_GetBlockPtr FormulaIndex,FormulaPtr
MoveWord [FormulaPtr]:#E_FormulaCells,Stop
MoveWord #E_FormulaData,Start
brl chkDone
formLoop
SpaceLong
AddWord Start,#3,y
PushWord [FormulaPtr]:y
dey
dey
PushWord [FormulaPtr]:y
dey
lda [FormulaPtr],y
and #$00FF
sta RefByte
pha
and #S_RecentlyChangedBit2
sta ChangedBit
PushLong SrcCell
Call S_GetRealCell
PullLong RealCell
Call S_GetRefCell,in=(RealCell:l,RefByte:w,DestCell:l)
PullWord [FormulaPtr]:Start
iny
PullLong [FormulaPtr]:y
AddWord Start,#5,Start
; ; This will fix some circularity problems ;
;
; lda ChangedBit
; beq cont1
;
; CmpLong RealCell,DestCell
; bne cont1
;
; MoveLong SrcCell,RealCell
;ont1 anop
lda RefByte
and #$0080
jeq singleRef
SpaceLong
AddWord Start,#3,y
PushWord [FormulaPtr]:y
dey
dey
PushWord [FormulaPtr]:y
dey
lda [FormulaPtr],y
and #$00FF
sta RefByte
pha
and #S_RecentlyChangedBit2
sta ChangedBit
PushLong SrcCell
Call S_GetRealCell
PullLong RealCell2
Call S_GetRefCell,in=(RealCell2:l,RefByte:w,DestCell:l)
PullWord [FormulaPtr]:Start
iny
PullLong [FormulaPtr]:y
AddWord Start,#5,Start
; ; This will fix some circularity problems ;
;
; lda ChangedBit
; beq cont2
;
; CmpLong RealCell2,DestCell
; bne cont2
;
; MoveLong SrcCell,RealCell2
;ont2 anop
Call S_NormalizeRange,in=(RealCell:l,RealCell2:l)
in #S_FixDependList:l ; 2 inputs on stack
XCall S_TraverseRange
bra chkDone
; This will fix some circularity problems
; The first fix solves the problem of the dest cell refering
; to the src cell, in which case the depend list is at the dest
; cell, but the src formula is being changed.
singleRef
CmpLong RealCell,SrcCell
bne cont4
MoveLong DestCell,RealCell
bra cont3
; This solves the problem of cell that refers (singly) to itself.
; The depend list is at the src cell, but the formula
; is already changed.
cont4
lda ChangedBit
beq cont3
CmpLong RealCell,DestCell
bne cont3
MoveLong SrcCell,RealCell
cont3
Call S_FixDependList,in=(RealCell:l)
chkDone
CmpWord Start,Stop
jlt formLoop
ProfileOut 6
RETURN
ENDP
END