mirror of
https://github.com/antoinevignau/source.git
synced 2025-01-04 04:31:04 +00:00
1 line
11 KiB
Plaintext
Executable File
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
|
|
|