        SUBT    > <wini>arm.FileSwitch.FSCommands - Filing system commands

; Sam says we can crap on r0-r6 in module *Commands

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

Access_Code ENTRY

        MOV     r4, #FSControl_Access

10      MOV     r1, r0                  ; First ep for below
        MOV     r2, r1                  ; Save first arg^
        BL      SkipOverNameAndSpaces
        Swap    r1, r2                  ; Reorder first and second args

30      MOV     r0, r4                  ; Restore rc. Second ep for below
        SWI     XOS_FSControl
        EXIT

; .............................................................................

Rename_Code ALTENTRY

        MOV     r4, #FSControl_Rename
;;;        MOV     r3, #-1
        B       %BT10

; .............................................................................

Shut_Code ALTENTRY

        MOV     r4, #FSControl_Shut
        B       %BT30

ShutDown_Code ALTENTRY

        MOV     r4, #FSControl_ShutDown
        B       %BT30

; .............................................................................
; Similar code fragments with one (optional) string arg

Cat_Code ALTENTRY

        MOV     r4, #FSControl_Cat

50      MOV     r1, r0                  ; Get arg^
        B       %BT30

Dir_Code ALTENTRY

        MOV     r4, #FSControl_Dir
        B       %BT50

Info_Code ALTENTRY

        MOV     r4, #FSControl_Info
        B       %BT50

FileInfo_Code ALTENTRY

        MOV     r4, #FSControl_FileInfo
        B       %BT50

LEx_Code ALTENTRY

        MOV     r4, #FSControl_LEx
        B       %BT50

Lib_Code ALTENTRY

        MOV     r4, #FSControl_Lib
        B       %BT50

Run_Code ALTENTRY

        MOV     r4, #FSControl_Run
        B       %BT50

LCat_Code ALTENTRY

        MOV     r4, #FSControl_LCat
        B       %BT50

Ex_Code ALTENTRY

        MOV     r4, #FSControl_Ex
        B       %BT50

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Construct a file consisting of name,CR ... out of the given dir

enumdir_entries * 24                    ; NB. Must be EVEN st. *6 -> WordAlign
enumdir_bsize   * enumdir_entries * 6   ; 24 names at ~5 or 6 chars each

EnumDir_Code ENTRY "r0-r1, r7, r9-r10" ; Low registers used sp relative

        LDR     wp, [r12]               ; Need it again !

        MOV     r1, r0
        BL      SkipOverNameAndSpaces   ; Point to output filename
        MOV     r9, r1
        MOV     r0, #open_write         ; Create for output
        BL      OpenFileWithWinge
        STRVS   r0, [sp]                ; Return error to Sam
        EXIT    VS
        MOV     r7, r1                  ; Save handle

        LDR     r14, [sp, #4]           ; Was there a supplied wildcard parm ?
        TEQ     r14, #3
        ADRNE   r1, fsw_wildstar        ; Match them all then
        MOVEQ   r1, r9
        BLEQ    SkipOverNameAndSpaces   ; Point to wildcard specifier
        MOV     r9, r1                  ; Remember space stripped w/c spec

        MOV     r4, #0                  ; Start at the beginning

        SUB     sp, sp, #enumdir_bsize  ; Create local frame

10 ; Loop geting batches of names

        BL      STestEscape             ; And ack if found. Yields r0 -> error
        BVS     %FT75

        CMP     r4, #-1                 ; Start point in dir. -1 means ended
        BEQ     %FT75                   ; Good exit

        MOV     r0, #OSGBPB_ReadDirEntries
        LDR     r1, [sp, #enumdir_bsize] ; Name^ passed in r0 stacked, not r1 !
        MOV     r2, sp
        MOV     r3, #enumdir_entries
        MOV     r5, #enumdir_bsize
        MOV     r6, r9                  ; Wild card specifier
        SWI     XOS_GBPB
        BVS     %FT75                   ; Close file and exit
        MOVS    r10, r3                 ; No names matched this time ?
        BEQ     %BT10                   ; Loop and get some more to match

        MOV     r1, r7                  ; Restore handle. R2 -> buffer still

20 ; Loop copying names out to file

        LDRB    r0, [r2], #1
        CMP     r0, #0                  ; Terminate string appropriately
        MOVEQ   r0, #10                 ; with a LineFeed char
        SWI     XOS_BPut                ; Preserves Z flag
        BVS     %FT75                   ; Close file and exit

        SUBEQS  r10, r10, #1            ; If done all chars (EQ ^) and done
        BNE     %BT20                   ; all the names we got (EQ then) then
        B       %BT10                   ; loop and get another batch


75      ADD     sp, sp, #enumdir_bsize  ; Destroy local frame

        STRVS   r0, [sp]                ; Return current error (if any) to Sam
        MOV     r2, psr
        MOV     r0, #0
        MOV     r1, r7
        SWI     XOS_Find
        STRVS   r0, [sp]                ; May modify it though
        TEQVCP  r2, #0                  ; V from op/Close
        EXIT

fsw_wildstar                            ; Used from all over
        DCB     "*", 0
        ALIGN

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

SetType_Code ENTRY "r0"

        MOV     r1, r0                  ; Get filename^
        BL      SkipOverNameAndSpaces   ; Point to string arg

        MOV     r0, #FSControl_FileTypeFromString
        SWI     XOS_FSControl

        MOVVC   r0, #OSFile_SetType

50      LDRVC   r1, [sp]                ; Get filename^
        SWIVC   XOS_File                ; Entered from below
        STRVS   r0, [sp]
        EXIT

; .............................................................................

Stamp_Code ALTENTRY

        MOV     r0, #OSFile_SetStamp
        B       %BT50

; .............................................................................

CDir_Code ALTENTRY

        CMP     r1, #1                  ; Just one parm given ? VClear
        MOVEQ   r4, #0                  ; Default size parm is zero
        BEQ     %FT90

        MOV     r1, r0                  ; -> filename
        BL      SkipOverNameAndSpaces
        MOV     r0, #(1 :SHL: 31) + 10  ; Default base 10, no bad terms
        SWI     XOS_ReadUnsigned        ; Read numeric parm (no. of entries)
        MOVVC   r4, r2                  ; r4 for OSFile

90      MOVVC   r0, #OSFile_CreateDir   ; Will datestamp itself
        B       %BT50

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

Up_Code ENTRY

        LDR     wp, [r12]               ; Actually need this for once !

        CMP     r1, #0                  ; No parms ? VClear
        MOVEQ   r2, #1                  ; Default number is one

        MOVNE   r1, r0                  ; Parm^
        MOVNE   r0, #(2_101 :SHL: 29) + 10 ; Decimal default, no bad terms
        MOVNE   r2, #128                ; Restrict range (256/2)
        SWINE   XOS_ReadUnsigned
        EXIT    VS

        CMP     r2, #0                  ; Zero = stay in CSD
        EXIT    EQ                      ; VClear

; Construct string of r2 '^'s on stack

        SUB     sp, sp, #256+8          ; Compatible number of '^'s possible
        MOV     r1, sp
        MOV     r3, #"^"
        MOV     r4, #"."
51      STRB    r3, [r1], #1
        SUBS    r2, r2, #1              ; Decrement count
        MOVEQ   r4, #CR                 ; Last dot mutates into terminator !
        STRB    r4, [r1], #1
        BNE     %BT51

        MOV     r0, #FSControl_Dir
        MOV     r1, sp
        SWI     XOS_FSControl

        ADD     sp, sp, #256+8
        EXIT

 [ hascopy
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Copy_Code ENTRY "r7, r8"

        LDR     wp, [r12]               ; Really do need it

        MOV     r1, r0
        MOV     r4, r1                  ; Save first arg^
        BL      SkipOverNameAndSpaces
        MOV     r5, r1                  ; Save second arg^
        BL      SkipOverNameAndSpaces
        MOV     r6, r1

        addr    r0, CopyOptsVariableNameCR ; Options for copy read from vbl
        ADD     r3, r0, #CopyOptsVariableDefault - CopyOptsVariableNameCR
        BL      SReadVariableToBuffer

        MOVVC   r3, #util_printok + util_confirm + util_verbose
        BLVC    SussCopyOptions

        ADD     sp, sp, r2              ; Restore sp after SReadVariable

        MOVVC   r1, r6
        BLVC    SussCopyOptions         ; Modify those using passed options

        MOVVC   r0, #FSControl_Copy
        MOVVC   r2, r5                  ; Restore dest^

 ]

 [ haswipe :LOR: hascopy

50      MOVVC   r1, r4                  ; Restore name^. Entry for below (now)
        MOVVC   r4, #0                  ; Start date = 1900
        MOVVC   r5, #0
        MOVVC   r6, #&FFFFFFFF          ; End date = a long time off
        MOVVC   r7, #&000000FF
        SWIVC   XOS_FSControl
        EXIT
 ]

 [ haswipe
; .............................................................................

Wipe_Code ALTENTRY ;ENTRY "r7"

        LDR     wp, [r12]               ; We do need it

        MOV     r1, r0
        MOV     r4, r1                  ; Save filename^
        BL      SkipOverNameAndSpaces
        MOV     r6, r1

        addr    r0, WipeOptsVariableNameCR ; Options for wipe read from vbl
        ADD     r3, r0, #WipeOptsVariableDefault - WipeOptsVariableNameCR
        BL      SReadVariableToBuffer

        MOVVC   r3, #util_printok + util_confirm + util_verbose ; NoRec,NoForce
        BLVC    SussWipeOptions

        ADD     sp, sp, r2              ; Restore sp after SReadVariable

        MOVVC   r1, r6
        BLVC    SussWipeOptions         ; Modify those using passed options

        MOVVC   r0, #FSControl_Wipe
        B       %BT50                   ; Common up for now
 ]

 [ hascount
; .............................................................................

Count_Code ALTENTRY ;ENTRY "r7"

        LDR     wp, [r12]               ; We do need it

        MOV     r1, r0
        MOV     r4, r1                  ; Save filename^
        BL      SkipOverNameAndSpaces
        MOV     r6, r1

        addr    r0, CountOptsVariableNameCR ; Options for count read from vbl
        ADD     r3, r0, #CountOptsVariableDefault - CountOptsVariableNameCR
        BL      SReadVariableToBuffer

        MOVVC   r3, #util_printok       ; NoConfirm, NoVerbose
        ORRVC   r3, r3, #util_recurse   ; Yes, it's not immediate
        BL      SussCountOptions

        ADD     sp, sp, r2              ; Restore sp after SReadVariable

        MOVVC   r1, r6
        BLVC    SussCountOptions        ; Modify those using passed options

        MOVVC   r0, #FSControl_Count
        B       %BT50                   ; Common up for now
 ]

 [ hascopy
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; In    r1 -> string

SussCopyOptions ENTRY

        SUBS    r8, r3, #0              ; r8 := r3. CSet

05      BL      SetAndGetUtilOption     ; Needs C from itself. Don't CMP !

        TEQ     r0, #"a"
        MOVEQ   r8, #util_noattr
        MOVEQ   r14, psr                ; Invert C as bit wrong way round
        TEQEQP  r14, #C_bit             ; for backwrods compatabilly-T
        BEQ     %BT05

        TEQ     r0, #"c"
        MOVEQ   r8, #util_confirm
        BEQ     %BT05

        TEQ     r0, #"d"
        MOVEQ   r8, #util_deletesrc
        BEQ     %BT05

        TEQ     r0, #"f"
        MOVEQ   r8, #util_force
        BEQ     %BT05

        TEQ     r0, #"l"
        MOVEQ   r8, #util_peekdest
        BEQ     %BT05

        TEQ     r0, #"n"
        MOVEQ   r8, #util_newer
        BEQ     %BT05

        TEQ     r0, #"p"
        MOVEQ   r8, #util_promptchange
        BEQ     %BT05

        TEQ     r0, #"q"
        MOVEQ   r8, #util_quick
        BEQ     %BT05

        TEQ     r0, #"r"
        MOVEQ   r8, #util_recurse
        BEQ     %BT05

        TEQ     r0, #"s"
        MOVEQ   r8, #util_restamp
        BEQ     %BT05

        TEQ     r0, #"t"
        MOVEQ   r8, #util_structureonly
        BEQ     %BT05

        TEQ     r0, #"v"
        MOVEQ   r8, #util_verbose
        BEQ     %BT05

        BL      TestBadOption
        EXIT
 ]

 [ haswipe
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; In    r1 -> string

SussWipeOptions ENTRY

        SUBS    r8, r3, #0              ; r8 := r3. CSet

05      BL      SetAndGetUtilOption     ; Needs C from itself. Don't CMP !

        TEQ     r0, #"c"
        MOVEQ   r8, #util_confirm
        BEQ     %BT05

        TEQ     r0, #"f"
        MOVEQ   r8, #util_force
        BEQ     %BT05

        TEQ     r0, #"r"
        MOVEQ   r8, #util_recurse
        BEQ     %BT05

        TEQ     r0, #"v"
        MOVEQ   r8, #util_verbose
        BEQ     %BT05

        BL      TestBadOption
        EXIT
 ]

 [ haswipe
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; In    r1 -> string

SussCountOptions ENTRY

        SUBS    r8, r3, #0              ; r8 := r3. CSet

05      BL      SetAndGetUtilOption     ; Needs C from itself. Don't CMP !

        TEQ     r0, #"c"
        MOVEQ   r8, #util_confirm
        BEQ     %BT05

        TEQ     r0, #"r"
        MOVEQ   r8, #util_recurse
        BEQ     %BT05

        TEQ     r0, #"v"
        MOVEQ   r8, #util_verbose
        BEQ     %BT05

        BL      TestBadOption
        EXIT
 ]

 [ hasutil
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; In    r1 -> string
;       r3 = bitset to alter
;       r8 = option to reset or set (CClear/CSet)

; Out   r0 = lowercased char
;       r1 updated past char if not term
;       CC if negated, CS otherwise

SetAndGetUtilOption ENTRY "r2"

        ORRCS   r3, r3, r8              ; If CSet, set option
        BICCC   r3, r3, r8              ; If CClear, clear option

        BL      FS_SkipSpaces           ; r0 = char
; ***^  LDRB    r0, [r1]
        EORS    r2, r0, #"~"            ; Negating next char ?
        LDREQB  r0, [r1, #1]!           ; Read next char and point at it
        CMP     r0, #space
        ADDHI   r1, r1, #1
        LowerCase r0, r14
        CMP     r2, #1                  ; 0 -> negated -> CC
        EXIT

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; In    r0 = char

; Out   VS, r0 -> error if not space or eoln

TestBadOption ROUT

        CMP     r0, #space
        BICLSS  pc, lr, #V_bit

        ADR     r0, ErrorBlock_BadCommandOption
        ORRS    pc, lr, #V_bit

        MakeErrorBlock BadCommandOption
 ]

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; *Configure/*Status FileSystem

FileSystem_Code ENTRY "r0-r4, fp"       ; r0 is return code if VSet. fp for err

        LDR     wp, [r12]               ; Possible errors may be composite
        MOV     fp, #0                  ; No frame, so don't set globalerror
  
        CMP     r0, #0                  ; *Configure<CR> ?
        BNE     %FT10

        SWI     XOS_WriteS
        DCB     "FileSystem <fs name>|<fs number>", LF,CR, 0
        ALIGN
05      STRVS   r0, [sp]                ; Bastard Bastard Bastard Bastard Basta
        EXIT


10      CMP     r0, #1                  ; *Status
        BNE     %FT20

        SWI     XOS_WriteS
        DCB     "FileSystem ", 0
        ALIGN
        BLVC    ReadFileCMOS

        MOV     r4, r2                  ; Remember fs number for printing

        SUB     sp, sp, #128            ; Print filing system name if present
        MOV     r0, #FSControl_ReadFSName
        MOV     r1, r2
        MOV     r2, sp
        MOV     r3, #128
        SWI     XOS_FSControl           ; no error returned
        LDRB    r14, [sp]               ; null -> not present
        TEQ     r14, #0
        BNE     %FT15                   ; [got fs name]

        MOV     r0, r4                  ; Print filing system number if not
        MOV     r1, sp
        MOV     r2, #8-1
        SWI     XOS_BinaryToDecimal
        MOVVC   r0, #0
        STRVCB  r0, [r1, r2]

15      MOVVC   r0, sp
        SWIVC   XOS_Write0
        SWIVC   XOS_NewLine
        ADD     sp, sp, #128
        B       %BT05                   ; Exit testing V


20      MOV     r1, r0                  ; Get command^
        LDRB    r0, [r1]                ; Do we have a parm ?
        CMP     r0, #"A"
        RSBCSS  r14, r0, #"Z"
        BCS     %FT25                   ; Lookup fs name
        CMP     r0, #"a"
        RSBCSS  r14, r0, #"z"
        BCS     %FT25                   ; Lookup fs name

        MOV     r0, #(2_11 :SHL: 30)    ; Detect naff term chars. Limit 255
        SWI     XOS_ReadUnsigned
        BVC     %FT30                   ; Always write number even if not there

25      MOVVC   r0, #FSControl_LookupFS
        SWIVC   XOS_FSControl           ; Look fs name up
        BVS     %BT05
        CMP     r2, #0                  ; Found it ?
        BEQ     %FT35
        MOV     r2, r1                  ; fs number in r1

30      BL      WriteFileCMOS           ; fs number in r2
        B       %BT05                   ; Exit testing V

35      BL      SetMagicFSDoesntExist
        ADR     r0, errorbuffer
        B       %BT05

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

ReadFileCMOS ENTRY "r0, r1"

        MOV     r0, #ReadCMOS

10      MOV     r1, #FileLangCMOS       ; We now own the whole byte
        SWI     XOS_Byte
        STRVS   r0, [sp]
        EXIT


WriteFileCMOS ALTENTRY

        MOV     r0, #WriteCMOS
        B       %BT10

        LTORG

        LNK     $fileprefix.FSErrors
