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