; Copyright 1996 Acorn Computers Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
;     http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; event_user_dragbox
; ==================

; In    r1 -> wimp_eventstr
;             [r1, #0]  dragbox x0
;             [r1, #4]          y0
;             [r1, #8]          x1
;             [r1, #12]         y1

; NB. The dirviewer that caused the drag may have been replaced, so we must
; deal solely with textual objects. (drag -> tasks get null events -> structure
; is liable to change)

; Out   all regs may be corrupted - going back to PollWimp
;       userdata corrupted

event_user_dragbox Entry
 [ DragASprite
        SWI     DragASprite_Stop
 ]
        ; Check the variety of drag, and ignore any more drags that we
        ; didn't start.
        LDRB    r14, drag_type
        STRB    r14, last_drag_type
        MOV     r10, #drag_ignore
        STRB    r10, drag_type
        CMP     r14, #drag_ignore
        EXIT    EQ

 [ autoscroll
        CMP     r14, #drag_selectmany
        CMPNE   r14, #drag_adjustmany
        MOVEQ   r0, #0
        SWIEQ   XWimp_AutoScroll
 ]

        CMP     r14, #drag_file
        BEQ     file_drag
        CMP     r14, #drag_copysave
        BEQ     copysave_drag
        CMP     r14, #drag_newdirsave
        BEQ     newdir_drag
        CMP     r14, #drag_selectmany
        BEQ     selectmany_drag
        CMP     r14, #drag_adjustmany
        BEQ     adjustmany_drag
        EXIT

file_drag       ROUT    ; NOENTRY
        LDR     r0, sel_whandle         ; If this has changed, we can do nowt
        TEQ     r0, #Nowt
 [ debug
 BNE %FT00
 DLINE "Selection handle has been zapped in the background. Goodbye"
00
 ]
        EXIT    EQ

        BL      FindDir
        BLEQ    InitSelection
        EXIT    NE                      ; [Waarg! Dir/Sel has vanished]


        ADR     r1, mousedata           ; Need pointer position when dropped
        SWI     XWimp_GetPointerInfo    ; r1 -> wimp_pointerinfo. Won't error

 [ debug
 Push "r0-r3"
 LDMIA r1, {r0-r3}
 DREG r0, "user_dragbox: x ",cc,Integer
 DREG r1, ", y ",cc,Integer
 DREG r2, ", ihandle ",cc
 DREG r3, ", whandle ",,Integer
 Pull "r0-r3"
 ]

        LDR     r0, windowhandle
        BL      FindDir                 ; r4 -> dirviewer block
 [ version >= 113
        BNE     SendSelectionToWindow   ; Dropped on a not directory viewer
 |
        BNE     %FT50                   ; [not dropped in a dirviewer]
 ]


        LDR     r14, sel_whandle
        TEQ     r14, r0
        EXIT    EQ                      ; [dropped into itself !]

 [ disallow_recursive_copies
        BL      is_copy_recursive
        EXIT    VS
 ]


; Dropped into another of our directory viewers - do copy/move
; by *Copy with appropriate postfix

 [ :LNOT: actionwind
        LDRB    r14, initshiftstate     ; If SHIFT-drag used to drag to another
        TEQ     r14, #&FF               ; dirviewer, copy files with D option.
 |
      [ version >= 138                  ; Check if configuration calls for filer_action
        MOV     R0,#&A1
        MOV     R1,#FileSwitchCMOS
        SWI     XOS_Byte
        MOVVS   R2,#0
        TST     R2,#4
        MOVNE   r0,#0
        MOVEQ   r0, #Filer_Action_Memory_CopyRename
        BLEQ    StartActionWindow
      |
      [ version >= 113
        MOV     r0, #Filer_Action_Memory_CopyRename
      ]
        BL      StartActionWindow
      ]
        BVS     %FT02
        TEQ     r0, #0
        BEQ     %FT02
        LDR     r1, sel_dirname
        SWI     XFilerAction_SendSelectedDirectory
        BVS     %FT02
        BL      SendSelectedFiles
        BVS     %FT02
        LDR     r1, [r4, #d_dirnamestore]
        BL      strlen
        ADD     r4, r3, #1
        MOV     r3, r1
        LDRB    r1, initshiftstate
        TEQ     r1, #&FF
        MOVNE   r1, #Action_Copying
        MOVEQ   r1, #Action_Moving
        [ OptionsAreInRAM
        LDRB    r2, fileraction_options
        |
        BL      ExtractCMOSOptions
        ]
        SWI     XFilerAction_SendStartOperation
        B       %FT49
02      ;
        CLRV
        LDRB    r14, initshiftstate
        TEQ     r14, #&FF
 ]

        ADRNE   r0, copy_commandtitle
        ADRNE   r6, copydrag_postfix

        ADREQ   r0, move_commandtitle
        ADREQ   r6, movedrag_postfix

        BL      messagetrans_lookup; SMC: look up command window title
        SWI     XWimp_CommandWindow
        EXIT    VS

        MOV     r7, #0                  ; Close command window with prompt

05      CMP     r5, #Nowt
        BEQ     %FT48                   ; [finished]

        ADR     r1, userdata
        ADR     r2, star_copy_prefix    ; 'copy src.leaf dst.leaf opt1 opt2'
        BL      strcpy
        LDR     r2, sel_dirname         ; +srcdirname
        BL      strcat_excludingspaces
        LDR     r2, sel_leafname        ; +leafname
        BL      AppendLeafnameToDirname
        ADR     r2, aspace
        BL      strcat
        LDR     r2, [r4, #d_dirnamestore] ; +dstdirname
        BL      strcat_excludingspaces
        LDR     r2, sel_leafname        ; +leafname
        BL      AppendLeafnameToDirname
        ADR     r2, star_copy_postfix   ; +static options
        BL      strcat
        MOV     r2, r6                  ; +dynamic options
        BL      strcat
 [ version >= 114
        BL      AppendConfirmVerboseForceAndNewer
 |
        BL      AppendConfirmAndVerbose
 ]
        ADR     r0, userdata
        SWI     XOS_CLI                 ; Doing this in a box
        BVS     %FT45

        Push    r4                      ; Want to preserve dest dirviewer^
        BL      GetSelection
        Pull    r4
        B       %BT05


45      BL      LocalReportError        ; Prints the error; gives 'Press SPACE'
        MOV     r7, #-1                 ; Close command window without prompt

48      MOV     r0, r7                  ; 'Press SPACE' if command printed 'owt
        SWI     XWimp_CommandWindow     ; Or close window without prompt if err

49      ;
 [ clearsel_copymove
        MOV     r2, #Nowt
        BL      ClearAllSelections
 ]
        B       %FT90                   ; go home



copy_commandtitle
        DCB     "TCopy", 0

move_commandtitle
        DCB     "TMove", 0

copydrag_postfix
        DCB     "~D", 0                 ; ~D(elete)

movedrag_postfix
        DCB     "D", 0                  ; D(elete)

star_copy_prefix
        DCB     "Copy ", 0

star_copy_postfix
 [ version >= 114
        DCB     " ~P~QR~T~LF", 0        ; Don't alter A(ccess),S(tamp)
                                        ; CMOS set for C(onfirm),V(erbose),N(ewer)
                                        ; CMOS Force doesn't have a *copy equivalent
 |
        DCB     " ~P~QR~T", 0           ; Don't alter A(ccess),L(ook),N(ewer)
                                        ;             S(tamp),F(orce)
                                        ; CMOS set for C(onfirm),V(erbose)
 ]
aspace  DCB     space, 0

adot    DCB     "."                     ; Share zero with ...
anull   DCB     0


        ALIGN


 [ version >= 113
SendSelectionToWindow
        BL      NobbleMenuTree
 |
50 ; Dropped selection in alien window, so send to window owner
 ]

 [ debugtask
        DREG    r13,"Entry R13 "
 ]

        LDR     r4, sel_dir             ; We overwrote this by doing FindDir

        STR     r4, was_seldir

 [ dragtobar
        MOV     r7, #0                  ; No directories dragged to the bar
 ]

 [ version >= 140                       ; Send Message_FilerSelection to window /icon.
        Push    "r0-r9,r14"
      [ debugtask
        DLINE   "Pushed r0-r9,r14"
        DLINE   "Sending Filer selection message"
      ]
        ADR     r1,userdata
        LDR     r0,[r1]
        STR     r0,[r1,#ms_data]
        LDR     r0,[r1,#4]
        STR     r0,[r1,#ms_data+4]
        LDR     r0,[r1,#8]
        STR     r0,[r1,#ms_data+8]
        LDR     r0,[r1,#12]
        STR     r0,[r1,#ms_data+12]     ; Copy bounding box.
      [ debugtask
        DREG    r13,"r13 on entry to GetItemBoxSize"
      ]
        BL      GetItemBoxSize
      [ debugtask
        DREG    r13,"r13 on exit from GetItemBoxSize"
      ]
        STR     r11,[r1,#ms_data+16]    ; Followed by x size of items
        STR     r14,[r1,#ms_data+20]    ; y size of items.
        LDRB    r14,[r4,#d_viewmode]
        STR     r14,[r1,#ms_data+24]    ; View mode for this directory.

; Now work out bounding box in rows and columns

        LDRB    r14,[r4,#d_filesperrow] ; Number of files per row.
        LDR     r11,[r4,#d_nfiles]      ; Number of objects in this directory.
        ADD     r0,r4,#d_headersize
        MOV     r2,#&80000              ; Start column
        MOV     r3,#-1                  ; End column.
        MOV     r4,#&80000              ; Start row
        MOV     r5,#-1                  ; End row
        MOV     r6,#0                   ; Current row
        MOV     r7,#0                   ; Current column
01
        CMP     r11,#0                  ; Reached the end?
        BEQ     %FT10

        LDRB    r8, [r0, #df_state]     ; Is current file selected ?
        TST     r8, #dfs_selected

        ORRNE   r8, r8, #dfs_wasselected
        BICEQ   r8, r8, #dfs_wasselected
        STRB    r8, [r0, #df_state]
        TST     r8, #dfs_selected

        BEQ     %FT02

        CMP     r6,r4                   ; Is current row the top one ?
        MOVLT   r4,r6

        CMP     r6,r5                   ; Is current row the bottom one ?
        MOVGT   r5,r6

        CMP     r7,r2                   ; Is current column the left most?
        MOVLT   r2,r7

        CMP     r7,r3                   ; Is current column the right most ?
        MOVGT   r3,r7
02
        ADD     r7,r7,#1
        CMP     r7,r14
        MOVGE   r7,#0
        ADDGE   r6,r6,#1
        ADD     r0,r0,#df_size
        SUB     r11,r11,#1
        B       %BT01                   ; Go do next file.

10
        STR     r2,[r1,#ms_data+28]
        STR     r4,[r1,#ms_data+32]
        STR     r3,[r1,#ms_data+36]
        STR     r5,[r1,#ms_data+40]

        [ NewMessageFilerSelection
        Push    "r1"
        ; Use Wimp_GetPointerInfo to add the x and y of the pointer to the
        ; FilerSelection message.
        ADD     r1, r1, #64
        SWI     Wimp_GetPointerInfo
        Pull    "r1"
        ]

        MOV     r0,#0
        STR     r0,[r1,#ms_myref]
        STR     r0,[r1,#ms_yourref]

        [ NewMessageFilerSelection
        MOV     r0,#ms_data+(13*4)
        |
        MOV     r0,#ms_data+11*4
        ]

        STR     r0,[r1,#ms_size]
        LDR     r0,=Message_FilerSelection
        STR     r0,[r1,#ms_action]
        MOV     r0,#17
        LDR     r2,windowhandle
        LDR     r3,iconhandle
        SWI     XWimp_SendMessage
      [ debugtask
        DREG    r13,"r13 before pull is "
      ]
        Pull    "r0-r9,r14"
      [ debugtask
;        DREG    PC,"PC is "
;        DLINE   "Pulled r0-r9,r14"
        DREG    r13,"r13 after pull is "
      ]
        CLRV                    ; For this not to work it has to be our menu.
      [ debugtask
        DLINE   "Filer selection message sent"
      ]
 ]

60      CMP     r5, #Nowt
        BEQ     %FT92                   ; [finished]

      [ debugtask
        DLINE   "Found selection"
      ]


 [ clearsel_copymove
        BL      ClearSelectedItem       ; Can do this here; not a CommandWindow
        EXIT    VS
 ]

 [ hastiny
        LDR     r0, windowhandle
        CMP     r0, #iconbar_whandle
        LDREQ   r0, iconhandle
        CMPEQ   r0, #-1
        BEQ     %FT80                   ; [dropped on empty part of iconbar]
 ]

 [ dragtobar
        LDR     r0, windowhandle
        CMP     r0, #iconbar_whandle
        LDREQ   r0, iconhandle
        CMPEQ   r0, #-1
        BEQ     %FT80                   ; [dropped on empty part of iconbar]
 ]

      [ debugtask
        DLINE   "Calculate position"
      ]


      [ version >=140
        Push    "r8,r9"
        LDR     r3,sel_filenumber
        LDR     r4, sel_dir
        LDR     r0,[r4,#d_nfiles]
        SUB     r8,r0,r3
        LDRB    r0,[r4,#d_filesperrow]
        DivRem  r9,r8,r0,r14            ; r9 = row, r8 = column
      ]

      [ debugtask
        DREG    r9,"row "
        DREG    r8,"column "
      ]
        LDR     r0, =Message_DataLoad   ; ep for below
        LDR     r1, sel_dirname
        LDR     r2, sel_leafname
        LDR     r3, sel_filetype
        LDR     r4, windowhandle
        LDR     r5, iconhandle
      [ debugtask
        DREG    r13,"r13 before SendMessage "
      ]
        BL      SendMessage             ; DataLoadAck may remove dir
      [ debugtask
        DREG    r13,"r13 after SendMessage "
      ]
      [ version >= 140
        Pull    "r8,r9"
      ]
        EXIT    VS

      [ debugtask
        DLINE   "Sent DataLoad message"
      ]

79      BL      GetSelection

        B       %BT60


 [ hastiny
80 ; Dropped in icon bar, so send into exile (if it's not a file !)

        LDR     r0, sel_filetype
        CMP     r0, #filetype_directory
        CMPNE   r0, #filetype_application
        BNE     %BT75                   ; [files passed on]

        ;ADR     r1, dirnamebuffer
        LDR     r1, dirnamebuffer
        LDR     r2, sel_dirname
        BL      strcpy
        LDR     r2, sel_leafname
        BL      AppendLeafnameToDirname

        BL      MakeTinyDir
        EXIT    VS
        B       %BT79
 ]

 [ dragtobar
80 ; Dropped in icon bar so Data_Open the object
        LDR     r3, sel_filetype

  [ version >= 117
        ; Files,directories,applications - everybody's welcome and will be opened
  |
        CMP     r3, #filetype_application       ; reject anything but applications
        BNE     %BT79
  ]

        LDR     r1, sel_dirname
        LDR     r2, sel_leafname
        ; r3 already has sel_filetype in it
        MOV     r4, #0                          ; broadcast this
        MOV     r5, #0                          ; Icon irrelevant
        BL      SendDataOpenMessage
        B       %BT79
 ]


90
      [ debugtask
        DLINE   "CloseInitiatingDir"
      ]
        BL      CloseInitiatingDir
      [ debugtask
        DLINE   "CloseInitiatingDir returned"
      ]
92
        TEQ     r7, #1
        LDREQ   r0, sel_whandle
        STREQ   r0, windowhandle
      [ debugtask
        DLINE   "About to exit"
      ]
        CLRV
 [ debugtask
        DREG    r13,"Exit R13 "
 ]
        EXIT

newdir_drag  ROUT

        SWI     XDragASprite_Stop

        ADR     r1, mousedata           ; Need pointer position when dropped
        SWI     XWimp_GetPointerInfo    ; r1 -> wimp_pointerinfo.
        LDR     r0,  windowhandle
        LDR     r14, newdirsubmenu
        TEQ     r0,  r14
        EXIT    EQ                      ; dropped on ourself

        BL      FindDir
        EXIT    NE                      ; not a dirviewer

        ADR     r1, userdata
        LDR     r2, [r4, #d_dirnamestore]
        BL      strcpy_excludingspaces  ; copy pathname

        MOV     r3, r1
        LDR     r1, newdirbox_text
        BL      FindLeafname
        MOV     r1, r3
        BL      AppendLeafnameToDirname
        MOV     r3, r1                  ; append leafname

        ;ADR     r1, dirnamebuffer
        LDR     r1, dirnamebuffer
        ADR     r2, star_cdir_prefix
        BL      strcpy
        MOV     r2, r3
        BL      strcat                  ; append filename to CDir command

        MOV     r0, r1
        BL      DoOSCLIInBox            ; Do the command

        BL      ClearAllSelections
        BL      NobbleMenuTree


        EXIT

star_cdir_prefix
        DCB     "CDir ", 0              ; Needs space
        ALIGN

 [ version >= 113
copysave_drag   ROUT    ; NOENTRY
 [ DragASprite
        SWI     XDragASprite_Stop
 ]

        LDR     r0, sel_whandle         ; If this has changed, we can do nowt
        TEQ     r0, #Nowt
 [ debug
 BNE %FT00
 DLINE "Selection handle has been zapped in the background. Goodbye"
00
 ]
        BEQ     %FT90

        BL      FindDir
        BLEQ    InitSelection
        BNE     %FT90                   ; Del/Sel disappeared - finish off

        ADR     r1, mousedata           ; Need pointer position when dropped
        SWI     XWimp_GetPointerInfo    ; r1 -> wimp_pointerinfo.

 [ version >= 138
        LDR     r0,  windowhandle
        LDR     r14, csavesubmenu
        TEQ     r0,  r14
        EXIT    EQ
 ]


75
        LDR     r0, windowhandle
        BL      FindDir                 ; r4 -> dirviewer block
        MOVNE   r0, #Nowt
        STRNE   r0, dirtoclose
        BNE     SendSelectionToWindow   ; Selection dropped on a not directory viewer

 [ disallow_recursive_copies
        BL      is_copy_recursive
        BVS     %FT90
 ]


; Dropped into another of our directory viewers - do copy
; by *Copy with appropriate postfix

        ; Start new task
      [ version >= 138                  ; Check if configuration calls for filer_action
        MOV     R0,#&A1
        MOV     R1,#FileSwitchCMOS
        SWI     XOS_Byte
        MOVVS   R2,#0
        TST     R2,#4
        MOVNE   r0,#0
        MOVEQ   r0, #Filer_Action_Memory_CopyRename
        BLEQ    StartActionWindow
      |
        MOV     r0, #Filer_Action_Memory_CopyRename
        BL      StartActionWindow
      ]
        BVS     %FT10           ; Task didn't get going
        TEQ     r0, #0          ;
        BEQ     %FT10           ; for one reason or another.

        ; Send source dir
        LDR     r1, sel_dirname
        SWI     XFilerAction_SendSelectedDirectory
        BVS     %FT10

        ; Send file(s) (there should only be one if we are here)
        BL      SendSelectedFiles
        BVS     %FT10

        ; Send leaf appended to destination dir
        ADR     r1, userdata
        LDR     r2, [r4, #d_dirnamestore]
        BL      strcpy_excludingspaces
        MOV     r3, r1
 [ version >= 117
        LDR     r1, csavebox_text
 |
        wsaddr  r1, csavebox_text
 ]
        BL      FindLeafname
        MOV     r1, r3
        BL      AppendLeafnameToDirname
        BL      strlen
        ADD     r4, r3, #1
        MOV     r3, r1
        MOV     r1, #Action_CopyLocal
        [ OptionsAreInRAM
        LDRB     r2, fileraction_options
        |
        BL      ExtractCMOSOptions
        ]
        SWI     XFilerAction_SendStartOperation
        B       %FT80

10      ;
        CLRV

        ADRL    r0, copy_commandtitle
        ADRL    r6, copydrag_postfix

        BL      messagetrans_lookup     ; SMC: look up command window title
        SWI     XWimp_CommandWindow
        BVS     %FT90

        MOV     r7, #0                  ; Close command window with prompt

        ADR     r1, userdata
        ADRL    r2, star_copy_prefix    ; 'copy src.leaf dst.leaf opt1 opt2'
        BL      strcpy
        LDR     r2, sel_dirname         ; +srcdirname
        BL      strcat_excludingspaces
        LDR     r2, sel_leafname        ; +leafname
        BL      AppendLeafnameToDirname
        ADRL    r2, aspace
        BL      strcat
        LDR     r2, [r4, #d_dirnamestore] ; +dstdirname
        BL      strcat_excludingspaces
        MOV     r0, r1
 [ version >= 117
        LDR     r1, csavebox_text
 |
        wsaddr  r1, csavebox_text
 ]
        BL      FindLeafname
        MOV     r1, r0
        BL      AppendLeafnameToDirname
        ADRL    r2, star_copy_postfix   ; +static options
        BL      strcat
        MOV     r2, r6                  ; +dynamic options
        BL      strcat
 [ version >= 114
        BL      AppendConfirmVerboseForceAndNewer
 |
        BL      AppendConfirmAndVerbose
 ]

        ADR     r0, userdata
        SWI     XOS_CLI                 ; Doing this in a box
        BVC     %FT30

        BL      LocalReportError        ; Prints the error; gives 'Press SPACE'
        MOV     r7, #-1                 ; Close command window without prompt

30      MOV     r0, r7                  ; 'Press SPACE' if command printed 'owt
        SWI     XWimp_CommandWindow     ; Or close window without prompt if err

80      ;
 [ clearsel_file_copy
        MOV     r2, #Nowt
        BL      ClearAllSelections
        BL      NobbleMenuTree
 |
        ; Only nobble the menu tree if the right button wasn't used.
        LDR     r2, init_buttonstate
        TST     r2, #button_right :OR: button_right_drag
        BLEQ    NobbleMenuTree
 ]
90
        EXIT
 ]

 [ version >= 140
        LTORG
 ]

 [ version >= 114
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;

selectmany_drag ROUT ; NOENTRY
        ; sel_dir unlikely to change, except to Nowt, so only check that
        LDR     r4, sel_dir
        TEQ     r4, #Nowt
        EXIT    EQ

        ; Get the work area origin and store it somewhere handy
        LDR     r0, [r4, #d_handle]
        BL      GetWorkAreaCoords
        EXIT    VS
        MOV     r3, x0
        MOV     r5, y1

        ; Extract the drag rectangle from the event
        LDMIA   r1, {x0, y0, x1, y1}

        ; Translate drag rectangle to relative coordinates
        SUB     x0, x0, r3
        SUB     y0, y0, r5
        SUB     x1, x1, r3
        SUB     y1, y1, r5

        ; Ensure ordering of x0, x1 and y0,y1
        CMP     x0, x1
        MOVGT   r0, x0
        MOVGT   x0, x1
        MOVGT   x1, r0
        CMP     y0, y1

        MOVGT   r0, y0
        MOVGT   y0, y1
        MOVGT   y1, r0

        LDR     r3, [r4, #d_nfiles]
        CMP     r3, #0
        EXIT    EQ

        ADD     r5, r4, #d_headersize
10
        BL      HitsFile
        BEQ     %FT20                   ; rats - it missed!

        ; Hah! found it
        LDRB    r1, [r5, #df_state]
        TST     r1, #dfs_selected
        BNE     %FT20                   ; its already selected
        ORR     r1, r1, #dfs_selected
        STRB    r1, [r5, #df_state]
        BL      UpdateFile
        EXIT    VS

20
        ADD     r5, r5, #df_size
        SUBS    r3, r3, #1
        BNE     %BT10

        EXIT

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;

adjustmany_drag ROUT ; NOENTRY
        ; sel_dir unlikely to change, except to Nowt, so only check that
        LDR     r4, sel_dir
        TEQ     r4, #Nowt
        EXIT    EQ

        ; Get the work area origin and store it somewhere handy
        LDR     r0, [r4, #d_handle]
        BL      GetWorkAreaCoords
        EXIT    VS
        MOV     r3, x0
        MOV     r5, y1

        ; Extract the drag rectangle from the event
        LDMIA   r1, {x0, y0, x1, y1}

        ; Translate drag rectangle to relative coordinates
        SUB     x0, x0, r3
        SUB     y0, y0, r5
        SUB     x1, x1, r3
        SUB     y1, y1, r5

        ; Ensure ordering of x0, x1 and y0,y1
        CMP     x0, x1
        MOVGT   r0, x0
        MOVGT   x0, x1
        MOVGT   x1, r0
        CMP     y0, y1
        MOVGT   r0, y0
        MOVGT   y0, y1
        MOVGT   y1, r0

        LDR     r3, [r4, #d_nfiles]
        CMP     r3, #0
        EXIT    EQ

        ADD     r5, r4, #d_headersize
10
        BL      HitsFile
        BEQ     %FT20                   ; rats - it missed!

        ; Hah! found it
        LDRB    r1, [r5, #df_state]
        EOR     r1, r1, #dfs_selected   ; Toggle its selectedness
        STRB    r1, [r5, #df_state]
        BL      UpdateFile
        EXIT    VS

20
        ADD     r5, r5, #df_size
        SUBS    r3, r3, #1
        BNE     %BT10

        EXIT
 ]

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; In    r1 -> string to append to

AppendConfirmAndVerbose Entry "r1, r3"

        BL      strlen
        ADD     r1, r1, r3

        [ OptionsAreInRAM
        LDRB     r3, fileraction_options
        |
        BL      ReadCMOSBits
        ]

        [ OptionsAreInRAM
        TST     r3, #Action_OptionConfirm
        |
        TST     r3, #confirm_cmos_bit   ; 0 -> no confirm
        ]

        MOVEQ   r14, #"~"
        STREQB  r14, [r1], #1
        MOV     r14, #"C"
        STRB    r14, [r1], #1

        [ OptionsAreInRAM
        TST     r3, #Action_OptionVerbose
        |
        TST     r3, #verbose_cmos_bit   ; 0 -> no verbose
        ]

        MOVEQ   r14, #"~"
        STREQB  r14, [r1], #1
        MOV     r14, #"V"
        STRB    r14, [r1], #1

        MOV     r14, #0
        STRB    r14, [r1], #1
        EXIT

 [ version >= 114
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; In    r1 -> string to append to

AppendConfirmVerboseAndForce Entry "r1, r3"

        BL      AppendConfirmAndVerbose

        BL      strlen
        ADD     r1, r1, r3

        [ OptionsAreInRAM
        LDRB     r3, fileraction_options
        TST     r3, #Action_OptionForce
        |
        BL      ReadCMOSBits
        TST     r3, #force_cmos_bit
        ]

        MOVEQ   r14, #"~"
        STREQB  r14, [r1], #1
        MOV     r14, #"F"
        STRB    r14, [r1], #1

        MOV     r14, #0
        STRB    r14, [r1], #1
        EXIT

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Appends LN or ~L~N
; In    r1 -> string to append to

AppendConfirmVerboseForceAndNewer Entry "r1, r3"

        BL      AppendConfirmAndVerbose

        BL      strlen
        ADD     r1, r1, r3

        [ OptionsAreInRAM
        LDRB      r3, fileraction_options
        TST     r3, #Action_OptionNewer
        |
        BL      ReadCMOSBits
        TST     r3, #newer_cmos_bit
        ]

        MOVEQ   r14, #"~"
        STREQB  r14, [r1], #1
        MOV     r14, #"N"
        STRB    r14, [r1], #1

        MOV     r14, #0
        STRB    r14, [r1], #1
        EXIT
 ]

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Close the dirviewer that an action (double-click, drag) was initiated from

CloseInitiatingDir EntryS "r0, r4"

        LDR     r4, dirtoclose
        TEQ     r4, #Nowt
        EXITS   EQ

        MOV     r14, #Nowt
        STR     r14, dirtoclose

        LDR     r0, [r4, #d_handle]
        BL      DeleteDir
        EXITS   VC

        STR     r0, [sp, #Proc_RegOffset]
        EXIT

 [ disallow_recursive_copies
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;  is_copy_recursive
; ===================
;
; In    r4 -> destination dir viewer
;       sel_xxx set for current selection
; Out   r0 scrambled and VC (not recursive)
;       r0->errorblock and VS (recursive)
;

        MakeErrorBlock  Filer_NoRecursion

is_copy_recursive Entry "r1-r7"
        ; Check dest dir starts same as source dir
        LDR     r1, sel_dirname
        BL      strlen_excludingspaces
        LDR     r2, [r4, #d_dirnamestore]
        BL      strncmp
        BNE     %FT99

        ; Check dest dir isn't source dir
        ADD     r2, r2, r3
        LDRB    r0, [r2]
        CMP     r0, #space
        BLE     %FT99

        TEQ     r0, #"."
        ADDEQ   r2, r2, #1
        BEQ     %FT10
        LDRB    r0, [r2, #-1]
        CMP     r0, #":"
        BNE     %FT99

;       Dest = source. or source ends in : and r2 points past the . or : respectively
10      MOV     r6, #"."
        LDR     r7, sel_dir
        LDR     r5, [r7, #d_filenames]
        LDR     r3, [r7, #d_nfiles]
        ADD     r7, r7, #d_headersize

20      ; Have we run out of entries?
        TEQ     r3, #0
        BEQ     %FT99

        ; Get the leaf name
        LDR     r1, [r7, #df_fileptr]
 [ not_16bit_offsets
        ADD     r1, r5, r1
 |
        ADD     r1, r5, r1, LSR #16
 ]

        ; Compare up to the . or terminator
        BL      strcmpTS
        BNE     %FT30

        ; If matched and its selected, then we're recursive
        LDRB    r0, [r7, #df_state]
        TST     r0, #dfs_selected
        BEQ     %FT30

        ; It is recursive
        ADR     r0, ErrorBlock_Filer_NoRecursion
        BL      LookupError
        EXIT

30      ; Move on to the next entry
        ADD     r7, r7, #df_size
        SUB     r3, r3, #1
        B       %BT20

99      ; Is not recursive
        CLRV
        EXIT
 ]


        END