mirror of
https://github.com/antoinevignau/source.git
synced 2024-11-19 22:31:52 +00:00
1 line
42 KiB
Plaintext
Executable File
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
|
|
|