Oscli 44 KB
Newer Older
Neil Turton's avatar
Neil Turton committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
; 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.
;
        TTL     => Oscli - main Oscli code and system commands.

17 18 19 20 21 22 23 24 25
;
;mjs performance enhancements for Ursula (ChocolateOscli)
;
Oscli_CHashValMask        *       &1f                  ;32-wide Command hashing, for commands within kernel
Oscli_MHashValMask        *       &ff                  ;256-wide Module hashing, for command groups in other modules
                                                       ; - kernel cmd hashed tables must be reorganised if Oscli_CHashValMask is changed
                                                       ; - UtilityModule MUST be first in module chain, if hashing in use


Neil Turton's avatar
Neil Turton committed
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
        MACRO
$l      CheckUID $reg, $tmp
$l      MOV      $tmp, #0
        LDR      $tmp, [$tmp, #OscliCBbotUID]
        CMP      $reg, $tmp
        MEND
; exits with HI if buffer OK.

;******************************************************************************
; redirection utility routines

; In:   R10 points at filename, V clear
;       R1 is type

; Out:  R0, R1, R12 corrupted, redirection done, flags preserved (or V set)

doredirect ROUT
Kevin Bracey's avatar
Kevin Bracey committed
43
           EntryS "R1, R2"
Neil Turton's avatar
Neil Turton committed
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
60         LDRB    R0, [R10], #1
           CMP     R0, #" "
           BEQ     %BT60
           MOV     R2, R1
           LDR     R1, =RedirectBuff
61         CMP     R0, #" "             ; we know it's terminated by space
           STRNEB  R0, [R1], #1
           LDRNEB  R0, [R10], #1
           BNE     %BT61
           SUB     R10, R10, #1
           MOV     R0, #13
           STRB    R0, [R1]
           LDR     R1, =RedirectBuff
           MOV     R0, #0
           CMP     R2, #&40
           LDREQB  R1, [R0, #RedirectInHandle]
           LDRNEB  R1, [R0, #RedirectOutHandle]
           STREQB  R0, [R0, #RedirectInHandle]
           STRNEB  R0, [R0, #RedirectOutHandle]
           CMP     R1, #0
           SWINE   XOS_Find             ; close any previous File
           MOV     R12, R1              ; don't really care if handle was invalid
           LDR     R1, =RedirectBuff
           ORR     R0, R2, #open_mustopen + open_nodir
           SWI     XOS_Find             ; Open the File
           BVS     abort_redirect       ; bad name etc
           CMP     R0, #0               ; worked?
           BEQ     %FT63
           CMP     R2, #&40
           MOV     R1, #0
           STREQB  R0, [R1, #RedirectInHandle]
Kevin Bracey's avatar
Kevin Bracey committed
75
           BEQ     %FT00
Neil Turton's avatar
Neil Turton committed
76 77 78 79 80 81 82 83
           STRNEB  R0, [R1, #RedirectOutHandle]
           MOVNE   R0, #WrchV
           ADRNEL  R1, RedirectWrch
           CMP     R12, #0              ; Ensure only vectored the once
           MOVEQ   R2, #0
           SWIEQ   XOS_Claim
           BVS     abort_redirect       ; Claim will leave "Sysheap full" msg.
00
Kevin Bracey's avatar
Kevin Bracey committed
84
           LDR     R2, [stack, #Proc_RegOffset]
Neil Turton's avatar
Neil Turton committed
85
           CMP     R2, #&C0
Kevin Bracey's avatar
Kevin Bracey committed
86
           EXITS   NE
Neil Turton's avatar
Neil Turton committed
87 88 89 90 91 92 93 94 95

; >> file, so move to EOF

           MOV     R1, #0
           LDRB    R1, [R1, #RedirectOutHandle]
           MOV     R0, #2               ; read extent
           SWI     XOS_Args
           MOVVC   R0, #1               ; write ptr
           SWIVC   XOS_Args
Kevin Bracey's avatar
Kevin Bracey committed
96
           EXITS   VC
Neil Turton's avatar
Neil Turton committed
97 98 99 100 101 102 103 104 105 106

           B       abort_redirect

           MakeErrorBlock   RedirectFail

63         ADR     R0, ErrorBlock_RedirectFail
         [ International
           BL      TranslateError
         ]
abort_redirect                          ; current error set
Kevin Bracey's avatar
Kevin Bracey committed
107
           EXITVS
Neil Turton's avatar
Neil Turton committed
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147


ParseRDNSpec        ROUT
; In : R11 points at string to test.
; Out : EQ/NE for "is it a rdnspec?". V always clear.
; If EQ : R11 points after filename
;         R10 points at start of filename
;         R1=&40 => redirect input,
;           =&80 => redirect output,
;           =&C0 => redirect & append output
         MOV        R1, #&40
01       LDRB       R10, [R11], #1
         CMP        R10, #" "
         BEQ        %BT01               ; skip leading spaces
         CMP        R10, #"<"
         BEQ        %FT04
         CMP        R10, #">"
         MOVNE      PC, lr
         MOV        R1, #&80
         LDRB       R10, [R11], #1
         CMP        R10, #">"
         MOVEQ      R1, #&C0
04       LDREQB     R10, [R11], #1
         CMP        R10, #" "
         MOVNE      PC, lr
         SUB        R10, R11, #1        ; filename start ptr
         Push      "R0"
02       LDRB       R0, [R11], #1
         CMP        R0, #" "
         BGT        %BT02
         Pull      "R0"
         MOV        PC, lr              ; it's EQ if had space at end.

         MakeErrorBlock StackFull

OscliStackFull
         ADR        R0, ErrorBlock_StackFull
       [ International
         BL         TranslateError
       ]
Kevin Bracey's avatar
Kevin Bracey committed
148 149 150 151
 [ No26bitCode
         SETV
         Pull      "pc"
 |
Neil Turton's avatar
Neil Turton committed
152 153
         Pull      "lr"
         ORRS       PC, lr, #V_bit
Kevin Bracey's avatar
Kevin Bracey committed
154
 ]
Neil Turton's avatar
Neil Turton committed
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181

;******************************************************************************
; Main OSCLI code

VecOsCli ROUT

; first check for rheum on the stack.
; Oscli will have pushed 5 registers when it calls module code : let's
; guarantee 256 bytes (=64 registers) for the module code
; so check half a K left, leaving 236 bytes for any interrupt processing.

         CheckSpaceOnStack  512, OscliStackFull, R10

         Push      "R0-R2"      ; lr on stack from caller

; first skip * and space

01       LDRB       R10, [R0], #1
         CMP        R10, #" "
         CMPNE      R10, #"*"
         BEQ        %BT01
         CMP        R10, #"%"
         LDREQB     R10, [R0]           ; fixed 29-Mar-89; was LDREQ
         CMP        R10, #13
         CMPNE      R10, #10
         CMPNE      R10, #0
         CMPNE      R10, #"|"
Kevin Bracey's avatar
Kevin Bracey committed
182
         Pull      "R0-R2, PC", EQ   ; V clear return
Neil Turton's avatar
Neil Turton committed
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260

; now check for redirection.
; Redirection setter ::= "{ " [ >= 1 Redirection spec] "}"
; where
; Redirection spec ::=  "> "filename" " | "< "filename" " | ">> "filename" "
; Also check terminator in first 256 chars.
         SUB        R11, R0, #1
         MOV        R1, #0
         ADD        R2, R0, #256
02       LDRB       R10, [R11], #1
         CMP        R11, R2
         BEQ        OscliLineTooLong
         CMP        R10, #13
         CMPNE      R10, #10
         CMPNE      R10, #0
         BEQ        %FT58
         CMP        R10, #""""
         EOREQ      R1, R1, R10
         CMP        R10, #"{"
         CMPEQ      R1, #0
         BNE        %BT02
         Push      "R11"
         LDRB       R10, [R11], #1
         CMP        R10, #" "
         BLEQ       ParseRDNSpec
         Pull      "R11", NE
         BNE        %BT02
60       BL         ParseRDNSpec
         BEQ        %BT60
         CMP        R10, #"}"
         Pull      "R11"
         BNE        %BT02
; R11 points 1 char after {
         Push      "R5, R6"
         BL         GetOscliBuffer    ; get a buffer
         SUB        R0, R0, #1
         MOV        R2, #0
50       LDRB       R10, [R0], #1
         CMP        R0, R11
         STRNEB     R10, [R5, R2]
         ADDNE      R2, R2, #1
         BNE        %BT50

61       BL         ParseRDNSpec
         BLEQ       doredirect
         BVS        RedirectionError  ; close any redirection set up
         BEQ        %BT61

53       LDRB       R10, [R11], #1
         CMP        R10, #" "
         BEQ        %BT53
         SUB        R11, R11, #1

52       LDRB       R10, [R11], #1
         STRB       R10, [R5, R2]
         ADD        R2, R2, #1
         CMP        R2, #OscliBuffSize
         BEQ        %FT51
         CMP        R10, #13
         CMPNE      R10, #10
         CMPNE      R10, #0
         BNE        %BT52
         MOV        R2, R6           ; buffer UID
         ADD        R0, R5, #1        ; point after 1st char.
         Pull      "R5, R6"
         B          %FT03

51       MOV       R2, R6            ; longer than 256
         ADR       R0, ErrorBlock_OscliLongLine
       [ International
         BL        TranslateError
       ]
RedirectionError
         BL        ReleaseBuff
         BL        OscliTidy        ; shut down the redirection just done.
         Pull     "R5, R6"
OscliFailure
         STR       R0, [stack]
Kevin Bracey's avatar
Kevin Bracey committed
261 262 263 264
 [ No26bitCode
         SETV
         Pull     "R0-R2, PC"
 |
Neil Turton's avatar
Neil Turton committed
265 266
         Pull     "R0-R2, lr"
         ORRS      PC, lr, #V_bit
Kevin Bracey's avatar
Kevin Bracey committed
267
 ]
Neil Turton's avatar
Neil Turton committed
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340

OscliLineTooLong
         ADR       R0, ErrorBlock_OscliLongLine
       [ International
         BL        TranslateError
       ]
         B         OscliFailure
         MakeErrorBlock  OscliLongLine

58       MOV       R2, #-1     ; naff buffer UID.
; Redirection dealt with. R0 points after 1st ch command
03
         Push     "R2"        ; save buffer UID

; now check for filing system name as prefix
         Push     "R3"
         MOV       R3, #0     ; j.i.c. fileswitch is dead!!
         SUB       R1, R0, #1
         MOV       R0, #FSControl_StarMinus
         SWI       XOS_FSControl

; here we have:
; V set if -nafffsname encountered
; VC: R2 = -1 if no fs name found
;     R3 = 0 if no specials encountered

         BVS       letmodprefatit
         CMP       R3, #0
         BEQ       letmodprefatit
         Pull     "R3"
         Push     "R2"        ; save "temp FS set" indicator
         ADR       R0, ErrorBlock_NoOscliSpecials
       [ International
         BL        TranslateError
       |
         SETV
       ]
         B         OscliExit
         MakeErrorBlock NoOscliSpecials

letmodprefatit
         Pull     "R3"
         Push     "R2"        ; save "temp FS set" indicator
         BL        CheckForModuleAsPrefix
         BVS       OscliExit

; special char checks
pfssss   LDRB      R10, [R1], #1
         CMP       R10, #" "
         BEQ       pfssss
         SUB       R0, R1, #1
         CMP       R2, #-1
         RSBLT     R11, R2, #0
         Push     "R2",LT
         BLT       OnlyOneModuleWanted

         CMP       R10, #"/"
         BEQ       %FT06

; see if skip macro expansion
         CMP       R10, #"%"
         LDREQB    R10, [R0], #1
         BEQ       %FT05

         CMP       R10, #"."    ; fudge .
         BEQ       %FT07

; try macro expansion : if find it, expand into a buffer.
; Also scan for parameters while expanding.
; R0 ptr to command, R10 first char.
; If success : Recursively call OSCLI for each line in expansion.

      Push  "R0, R3-R6"
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385

  [ Oscli_QuickAliases
    ;
    ;at least make a vague attempt not to run like a drain - since we can do a binary
    ;chop search for an exactly known var name, do this unless command is abbreviated
    ;
      ADR    R6,AliasStr_QA
      LDR    R3,=AliasExpansionBuffer      ; construct the alias name here
      MOV    R5,#6
oqa_loop1                                  ; bung in "ALIAS$"
      LDRB   R4,[R6],#1
      STRB   R4,[R3],#1
      SUBS   R5,R5,#1
      BNE    oqa_loop1
      MOV    R6,R0
      ADRL   R2, Up_ItAndTerm_Check_Table
oqa_loop2                                  ; bung in command, upper cased
      LDRB   R4,[R6],#1
      CMP    R4,#&80                       ; char in table ?
      LDRCCB R4,[R2,R4]
      STRB   R4,[R3],#1
      CMP    R4,#0
      BNE    oqa_loop2
      LDRB   R4,[R3,#-2]                   ; pick up last char of command
      CMP    R4,#"."
      BEQ    oqa_treacletime               ; it's abbreviated, go to slow code
      LDR    R3,=AliasExpansionBuffer
      Push   "r6,r7"
      BL     VarFindIt_QA                  ; quick binary chop type stuff
      Pull   "r6,r7",EQ
      BEQ    oqa_quicksilvertime_noalias   ; no alias - carry on
;found alias
      MOV    R0,#-1                        ; special, VarFindIt skipping call (r5,r6,r7 from VarFindIt_QA)
      MOV    R1,R3                         ; output buffer
      MOV    R2,#256
      MOV    R3,#0
      MOV    R4,#VarType_Expanded
      SWI    XOS_ReadVarVal                ; expand it
      Pull   "r6,r7"
      SUB    R6,R6,#1                      ; arg ptr
      B      oqa_quicksilvertime_alias
oqa_treacletime
;
  ] ;Oscli_Quickaliases

Neil Turton's avatar
Neil Turton committed
386 387 388 389 390 391 392 393 394 395
    [ International
      MOV    R3,#0
      LDRB   R6,[R3,#ErrorSemaphore]            ; We are about to get lots of buffer overflow errors,
      SUB    R6,R6,#1
      STRB   R6,[R3,#ErrorSemaphore]
    ]
      MOV    R6, R0
      MOV    R3, #:LEN: "Alias$"
31    SUB    R3, R3, #:LEN: "Alias$"
      MOV    R2, #-1        ; negative length means just look for it.
396
      ADRL   R0, AliasStr
Neil Turton's avatar
Neil Turton committed
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453
      SWI    XOS_ReadVarVal
      CMP    R2, #0         ; V always set anyway
    [ International
      LDREQB R0,[R2,#ErrorSemaphore]
      ADDEQ  R0,R0,#1
      STREQB R0,[R2,#ErrorSemaphore]
    ]
      BEQ    %FT10

      ADD   R3, R3, #:LEN: "Alias$"

; match $R6 with $R3

      MOV   R1, #0                         ; offset
32    LDRB  R4, [R6, R1]
      LDRB  R5, [R3, R1]
      CMP   R4, #&80                       ; in table ?
      ADRCCL R2, Up_ItAndTerm_Check_Table
      LDRCCB R4, [R2, R4]
      CMP   R4, #" "
      CMPLE R5, #" "
      BLE   %FT33
      UpperCase R5, R2
      CMP   R4, R5
      ADDEQ R1, R1, #1
      BEQ   %BT32
      CMP   R1, #0
      BEQ   %BT31                        ; failed
      CMP   R5, #" "
      BLE   %BT31
      CMP   R4, #"."
      BNE   %BT31
      ADD   R1, R1, #1
33
; success : copy name, read value

    [ International
      MOV   R4,#0
      LDRB  R0,[R4,#ErrorSemaphore]
      ADD   R0,R0,#1
      STRB  R0,[R4,#ErrorSemaphore]     ; We can go back to translating errors.
    ]

      SUB   R3, R3, #:LEN: "Alias$"
99    LDR   R0, =AliasExpansionBuffer
      ADD   R6, R6, R1                       ; save arglist ptr
      MOV   R4, #0
34    LDRB  R5, [R3], #1
      STRB  R5, [R0, R4]
      ADD   R4, R4, #1
      CMP   R5, #0
      BNE   %BT34
      MOV   R1, R0               ; output buffer same as input!
      MOV   R2, #256
      MOV   R3, #0
      MOV   R4, #VarType_Expanded
      SWI   XOS_ReadVarVal
454 455 456
  [ Oscli_QuickAliases
oqa_quicksilvertime_alias
  ]
Neil Turton's avatar
Neil Turton committed
457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517
      BVS   AliasOscliTooLong
      MOV   R3, #13
      STRB  R3, [R1, R2]

      MOV    R3, R1
      MOV    R0, R6              ; arglist
      MOV    R4, R2              ; no of chars got.
      BL     GetOscliBuffer      ; gives buffer ptr in R5, ID in R6
      MOV    R1, R5
      MOV    R2, #OscliBuffSize
      SWI    XOS_SubstituteArgs
      BVS    AliasOscliTooLong

; Whew! Now ready to recursively call OSCLI with all lines in the buffer.
      MOV    R0, R1
      ADD    R2, R1, R2
43    SWI    XOS_CLI
      BVS    %FT46
      CheckUID R6, R1    ; check buffer still valid.
      BLS    FailInAlias
44    LDRB   R1, [R0], #1
      CMP    R1, #13
      CMPNE  R1, #10
      CMPNE  R1, #0
      BNE    %BT44
      CMP    R0, R2
      BLO    %BT43
      MOV    R2, R6
      BL     ReleaseBuff ; release buffer, UID in R2
      Pull  "R0, R3-R6"
      CLRV
      B      OscliExit

      MakeErrorBlock  OscliTooHard

FailInAlias
      CheckUID R2, R1
      BLGT   ReleaseBuff
      ADR    R0, ErrorBlock_OscliTooHard
    [ International
      BL     TranslateError
    ]
46    STR    R0, [stack]
      Pull  "R0, R3-R6"
      SETV
      B      OscliExit

AliasOscliTooLong
      MOV    R2, R6            ; buffer UID
      BL     ReleaseBuff
      Pull  "R0, R3-R6"
      ADRL   R0, ErrorBlock_OscliLongLine
    [ International
      BL     TranslateError
    |
      SETV
    ]
      B      OscliExit

      LTORG

518 519 520
  [ Oscli_QuickAliases
AliasStr_QA = "ALIAS$", 0
  ]
Neil Turton's avatar
Neil Turton committed
521 522 523 524 525
AliasStr = "Alias$*", 0
AliasDot = "Alias$"
dotstring = ".", 0
      ALIGN

526 527 528
  [ Oscli_QuickAliases
oqa_quicksilvertime_noalias
  ]
Neil Turton's avatar
Neil Turton committed
529 530 531 532 533 534 535 536
10  ; Failed macro expansion.
         Pull   "R0, R3-R6"

; try for system command first.
05       LDRB      R1, [R0]                     ; quick check for . tho
         CMP       R1, #"."
         BEQ       PercentDot

537 538 539 540 541 542 543 544 545 546
  [ Oscli_HashedCommands
         BL        Oscli_cmd_hashsum            ; => hash value in r1
         MOV       r2,#0
         STR       r1,[r2,#Oscli_CmdHashSum]
         CMP       r1,#0
         BEQ       oscli_sysabbrevation
         BL        SysCommsHashedLookup
         B         oscli_syslook_done
oscli_sysabbrevation
  ]
Neil Turton's avatar
Neil Turton committed
547 548
         ADRL      R1, SysCommsModule
         MOV       R2, #SCHCTab-SysCommsModule
Kevin Bracey's avatar
Kevin Bracey committed
549
         SEC                                    ; carry set means sys module
Neil Turton's avatar
Neil Turton committed
550
         BL        ModCommsLookUp
551
oscli_syslook_done
Neil Turton's avatar
Neil Turton committed
552 553
         BCS       OscliExit

554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592
  [ Oscli_HashedCommands
         ;now try UtilityModule, if non-abbreviated command
         Push      "R2"
         MOV       r2,#0
         LDR       r1,[r2,#Oscli_CmdHashSum]
         CMP       r1,#0
         Pull      "R2",EQ
         BEQ       oscli_modabbreviation
         BL        UtilCommsHashedLookup
         ADDCS     stack, stack, #4                  ;discard R2
         BCS       OscliExit
         ;now try list of modules on hash value
         MOV       r2,#0
         LDR       r1,[r2,#Oscli_CmdHashSum]
         AND       r1,r1,#Oscli_MHashValMask
         LDR       r11,[r2,#Oscli_CmdHashLists]
         CMP       r11,#0
         LDRNE     r11,[r11,r1,LSL #2]
         CMPNE     r11,#0
         BEQ       %FT75
         Push      "r3,r4"
         ADD       r3,r11,#8
         LDR       r4,[r11,#4]
         ADD       r4,r4,#1
oscli_hlist_loop
         SUBS      r4,r4,#1
         Pull      "r3,r4",EQ
         BEQ       %FT75
         LDR       R2,[stack,#2*4]
         CMP       R2, #0
         Pull      "r3,r4",MI
         BMI       OneModule_Failed
         LDR       R11,[R3],#4
         LDR       R1, [R11, #Module_code_pointer]
         LDR       R2, [R1, #Module_HC_Table]
         CMP       R2, #0
         BEQ       oscli_hlist_loop
         LDR       R12, [R11, #Module_incarnation_list] ; preferred life
         ADD       R12, R12, #Incarnation_Workspace
Kevin Bracey's avatar
Kevin Bracey committed
593
         CLC
594 595 596 597 598 599 600 601
         BL        ModCommsLookUp
         BCC       oscli_hlist_loop
         Pull      "r3,r4"
         ADD       stack,stack,#4
         B         OscliExit
oscli_modabbreviation
  ] ;Oscli_HashedCommands

Neil Turton's avatar
Neil Turton committed
602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617
; now try looking round the modules.
         MOV       R11, #Module_List
         Push     "R2"
74       LDR       R2, [stack]
         CMP       R2, #0
         BMI       OneModule_Failed
         LDR       R11, [R11, #Module_chain_Link]
         CMP       R11, #0
         BEQ       %FT75
OnlyOneModuleWanted
         LDR       R1, [R11, #Module_code_pointer]
         LDR       R2, [R1, #Module_HC_Table]
         CMP       R2, #0
         BEQ       %BT74
         LDR       R12, [R11, #Module_incarnation_list] ; preferred life
         ADD       R12, R12, #Incarnation_Workspace
Kevin Bracey's avatar
Kevin Bracey committed
618
         CLC
Neil Turton's avatar
Neil Turton committed
619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636
         BL        ModCommsLookUp
         BCC       %BT74
         ADD       stack, stack, #4           ; discard R2
         B         OscliExit

75
  ; not in a module : try for current filing system command
         STR       R0, [stack]                 ; pull R2, push R0
         MOV       R0, #FSControl_ReadModuleBase
         SWI       XOS_FSControl
         Pull     "R0"
         CMP       R1, #0
         BEQ       NoFSCommands                  ; no selected FS!
         MOV       R12, R2                       ; module's workspace ptr
         LDR       R2, [R1, #Module_HC_Table]
         CMP       R2, #0
         BEQ       SecondaryFSCTab
         ORR       R2, R2, #&80000000            ; FS command needed flag
Kevin Bracey's avatar
Kevin Bracey committed
637
         CLC
Neil Turton's avatar
Neil Turton committed
638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654
         BL        ModCommsLookUp
         BCC       SecondaryFSCTab
         B         OscliExit

SecondaryFSCTab
         Push     "R0"
         MOV       R0, #FSControl_ReadSecondaryModuleBase
         SWI       XOS_FSControl
         Pull     "R0"
         MOVVS     R1, #0
         CMP       R1, #0
         BEQ       NoFSCommands
         MOV       R12, R2                       ; module's workspace ptr
         LDR       R2, [R1, #Module_HC_Table]
         CMP       R2, #0
         BEQ       NoFSCommands
         ORR       R2, R2, #&80000000            ; FS command needed flag
Kevin Bracey's avatar
Kevin Bracey committed
655
         CLC
Neil Turton's avatar
Neil Turton committed
656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685
         BL        ModCommsLookUp
         BCC       NoFSCommands
         B         OscliExit

NoFSCommands
         MOV       R1, #Service_UKCommand
         BL        Issue_Service
         CMP       R1, #0
         BNE       UKCNotClaimed
         CMP       R0, #0                        ; any error?
         SETV      NE                            ; V clear if EQ
         B         OscliExit

OneModule_Failed
         ADD       stack, stack, #4
         ADRL      R0, ErrorBlock_BadCommand
      [  International
         BL        TranslateError
      |
         SETV
      ]
         B         OscliExit

UKCNotClaimed
         MOV       R1, R0
DoFSCV_Run
         MOV       R0, #FSControl_RUN
71       SWI       XOS_FSControl
OscliExit
         Pull     "R2"
Kevin Bracey's avatar
Kevin Bracey committed
686 687
         SavePSR   R1
         Push     "R0"
Neil Turton's avatar
Neil Turton committed
688 689 690
         CMP       R2, #0                        ; -ve means no FS selected.
         MOVGE     R0, #FSControl_RestoreCurrent
         SWIGE     XOS_FSControl
Kevin Bracey's avatar
Kevin Bracey committed
691
         Pull     "R0"
Neil Turton's avatar
Neil Turton committed
692 693 694 695 696 697 698

         Pull     "R2"
         CMP       R2, #-1
         BEQ       %FT80
         BL        ReleaseBuff
         BL        RemoveOscliCharJobs  ; shut down redirection
80       TST       R1, #V_bit
Kevin Bracey's avatar
Kevin Bracey committed
699 700 701 702 703 704 705
         BNE       %FT81
         CLRV
         Pull     "R0-R2, pc"
81
         SETV
         ADD       sp, sp, #4
         Pull     "R1-R2, pc"
Neil Turton's avatar
Neil Turton committed
706 707 708 709 710 711 712

06       ADD       R1, R0, #1       ; */ so skip the /, do RUN reason code
         B         DoFSCV_Run

07
         Push     "R0, R3-R6"
         MOV       R6, R0
713
         ADRL      R0, AliasDot
Neil Turton's avatar
Neil Turton committed
714 715 716 717 718 719 720 721 722 723 724 725
         MOV       R3, #0
         MOV       R2, #-1         ; negative length means just look for it.
         SWI       XOS_ReadVarVal
         CMP       R2, #0          ; V always set anyway
         MOVNE     R1, #1          ; index to step past .
         BNE       %BT99
         Pull     "R0, R3-R6"
PercentDot                        ; entry for *%.
         ADD       R1, R0, #1
         MOV       R0, #FSControl_CAT   ; *., skip .
         B         %BT71

726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791
;***************************************************************************

  [ Oscli_HashedCommands
;
; - routine to compute hash value for unabbreviated commands
; - does not apply mask to hash value (since different hash widths are
;   required in different cases)
;
; hash value = sum of all chars of command, excluding terminator, all
;              chars being processed through Up_ItAndTerm_Check_Table
;
; entry:
; R0 -> command
; exit:
; R1 =  hash value, or 0 if invalid (abbreviation encountered)
;
Oscli_cmd_hashsum ROUT
         Push   "r0,r2-r3,lr"
         MOV    r1,#0
         ADRL   r2, Up_ItAndTerm_Check_Table
         B      %FT15
10
         ADD    r1,r1,r3
15
         LDRB   r3,[r0],#1
         CMP    r3,#&80
         LDRCCB r3,[r2,r3]
         CMP    r3,#"."
         BEQ    %FT30
         CMP    r3,#0
         BNE    %BT10
20
         Pull   "r0,r2-r3,PC"
30
         MOV    r1,#0
         Pull   "r0,r2-r3,PC"
;
;special entry of ModCommsLookUp, for hashed lookup of commands in SysCommsModule
;entry: R0 -> command, r1 = hash value of command
;
SysCommsHashedLookup ROUT
         Push   "R0, R2-R10, lr"
;
;first a fudge, to allow old syntax (no space before first, numeric, parameter)
;for *fx, *key, *opt and *tv - look for '&' or a numeric char at R0 + 2, 3 or 4
;
         MOV    R4, #2
schl_fudgeloop
         LDRB   R2, [R0,R4]
         CMP    R2, #' '
         BLS    schl_nofudge
         CMP    R2, #'&'
         BEQ    schl_fudge
         CMP    R2, #'0'
         BLO    schl_nofudgesofar
         CMP    R2, #'9'
         BLS    schl_fudge
schl_nofudgesofar
         ADD    R4, R4, #1
         CMP    R4, #4
         BLS    schl_fudgeloop
schl_nofudge
         AND    R4, R1,#Oscli_CHashValMask  ;hash value, masked for command hashing
         ADRL   R1, SysCommsModule
         ADRL   R2, SysCoHashedCmdTab
         LDR    R2, [R2, R4, LSL #2]        ;command list for this hash value
Kevin Bracey's avatar
Kevin Bracey committed
792
         SEC                                ;carry set means sys module
793 794 795 796 797
         B      ModCommsLookUp_AltEntry
schl_fudge
         ADRL   R1, SysCommsModule
         ADRL   R2, SHC_fudgeulike
         SUB    R2, R2, R1                          ;fudge command list (offset)
Kevin Bracey's avatar
Kevin Bracey committed
798
         SEC                                        ;carry set means sys module
799 800 801 802 803 804
         B      ModCommsLookUp_AltEntry

;
;special entry of ModCommsLookUp, for hashed lookup of commands in UtilityMod
;entry: R0 -> command, r1 = hash value of command
;
805

806 807 808 809 810 811
UtilCommsHashedLookup ROUT
         Push   "R0, R2-R10, lr"
         AND    R4, R1,#Oscli_CHashValMask  ;hash value, masked for command hashing
         ADRL   R1, UtilityMod
         ADRL   R2, UtilHashedCmdTab
         LDR    R2, [R2, R4, LSL #2]        ;command list for this hash value
Kevin Bracey's avatar
Kevin Bracey committed
812
         CLC
813 814 815 816
         B      ModCommsLookUp_AltEntry
;
  ] ;Oscli_HashedCommands

Neil Turton's avatar
Neil Turton committed
817 818 819 820 821 822 823 824 825 826 827 828 829 830
;***************************************************************************

; Routine to look through a module table for a command, and call it.
; Set up R12 yourself if needed.
; R0 points at command to find
; R1 points at module
; R2 offset of command table : top bit set for "want FS command"
; C set means allow messy matching, i.e. it's the system command table

; Return C set if found and called, V flag from code called
; Might not return if module starts up as current object.

ModCommsLookUp ROUT
         Push   "R0, R2-R10, lr"
831 832 833
  [ Oscli_HashedCommands
ModCommsLookUp_AltEntry
  ]
Neil Turton's avatar
Neil Turton committed
834 835 836 837 838
         MOV     R4, #0   ; want all flags clear
         TEQ     R2, #0   ; don't corrupt C!
         MOVMI   R4, #FS_Command_Flag
         BICMI   R2, R2, #&80000000
         BL      FindItem
Kevin Bracey's avatar
Kevin Bracey committed
839 840 841 842
         BLCS    %FT05
         CLC                      ; clears C and V
         Pull   "R0, R2-R10, PC"
05
Neil Turton's avatar
Neil Turton committed
843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011
         Push    r4               ; save pointer in case needed for syntax mess

; check number of arguments, error with syntaxmessage if naff.

         ADD     R2, R2, R1       ; get R2 back to pointer.
         ADD     R0, R0, R3       ; point at terminator.
09       LDRB    R4, [R0], #1
         CMP     R4, #" "        ; skip spaces.
         BEQ     %BT09
         MOV     R3, R1          ; hang on to module ptr.
         MOV     R1, #0          ; no of parms.
         MOV     R7, #-1         ; flag for buffer got for GSTRANSing

         MOV     R6, R0
         SUB     R0, R0, #1

; Now we have :
; R0 -> commtail, ready for module
; R1 number of parameters
; R2 -> info block for command
; R3 -> module
; R4 current char
; R5 execute offset
; R6 working commtail ptr
; R7 -1 or buffer UID
; R8 becomes gstrans map
; R9 may be a workin gstrans map copy
; R10 may be a working buffer ptr for copying

         LDRB    R8, [R2, #5]    ; get gstrans_map
         MOVS    R9, R8
         BEQ     nogstransingta

         Push   "R2, R5, R6"
         BL      GetOscliBuffer
         MOV     R0, R5          ; buffer ptr
         MOV     R7, R6          ; buffer UID
         MOV     R10, #0         ; buffer offset for copying
         Pull   "R2, R5, R6"

nogstransingta
         CMP     R4, #13         ; check for more to scan
         CMPNE   R4, #10
         CMPNE   R4, #0
         BEQ     %FT12

         MOVS    R9, R9, LSR #1
         BCC     stripnextparm

    ; gstrans next ; scan afterwards for naffchars
         Push   "R0-R2"

         ADD     R1, R0, R10                  ; buffer pointer
         RSB     R2, R10, #OscliBuffSize      ; room left
         ORR     R2, R2, #GS_Spc_term

         SUB     R0, R6, #1                   ; parameter pointer
         SWI     XOS_GSTrans
         BCS     buffer_overflowed_oh_bother
         BVS     bad_string

         CMP     R2, #0
         BEQ     preversion_detectified       ; empty expansions are naff
         ADD     R10, R10, R2
nastycharscan
         LDRB    R2, [R1], #1
         CMP     R2, #&7F
         CMPNE   R2, #" "
         BLE     preversion_detectified
         CMP     R1, R10
         BLT     nastycharscan

         MOV     R6, R0
         Pull   "R0-R2"
         B       next_parameter

preversion_detectified
         ADR     R0, ErrorBlock_BadParmString
       [ International
         BL      TranslateError
       ]
         B       pgstcomm
buffer_overflowed_oh_bother
         ADRL    R0, ErrorBlock_OscliLongLine
       [ International
         BL      TranslateError
       ]
         B       pgstcomm
bad_string
         ADR     R0, ErrorBlock_BadParmString
       [ International
         BL      TranslateError
       ]
pgstcomm
         STR     R0, [stack]
         MOV     R2, R7
         BL      ReleaseBuff
         Pull   "R0-R2, r4"
         B       unpleasantness_in_ModCommsLookUp

         MakeErrorBlock   BadParmString

AddCharForGSTP
         CMP     R8, #0
         MOVEQ   PC, lr
         CMP     R10, #OscliBuffSize
         STRLTB  R4, [R0, R10]
         ADDLT   R10, R10, #1
         MOVLT   PC, lr
         Push   "R0-R2"
         B       buffer_overflowed_oh_bother

stripnextparm
         Push   "R11"
         CMP     R4, #""""
         MOVEQ   R11, #&80000000
         ORREQ   R1, R1, R11
         MOVNE   R11, #0
stripnextchar
         BL      AddCharForGSTP
         LDRB    R4, [R6], #1
         CMP     R4, #""""
         EOREQ   R1, R1, R11
         CMP     R4, #" "
         TSTEQ   R1, #&80000000
         BEQ     parmfinished
         CMP     R4, #13
         CMPNE   R4, #10
         CMPNE   R4, #0
         BNE     stripnextchar
parmfinished
         BIC     R1, R1, #&80000000
         Pull   "R11"

next_parameter
         MOV     R4, #" "
         BL      AddCharForGSTP
         SUB     R6, R6, #1

30       LDRB    R4, [R6], #1
         CMP     R4, #" "
         BEQ     %BT30

         ADD     R1, R1, #1
         B       nogstransingta  ; next parameter

  ; parameters counted : check number

12       BL      AddCharForGSTP   ; terminate the copy

         BIC     R1, R1, #&80000000
         LDR     R4, [R2, #4]
         MOV     R6, R4, LSR #16  ; max no parms
         AND     R6, R6, #&FF
         AND     R4, R4, #&FF     ; min no parms
         CMP     R1, R4
         CMPGE   R6, R1
         BLT     %FT11

   ; checks finished : call the man.

         Push   "R7"              ; j.i.c. module writer can't read

         MOV     lr, PC           ; make link
         ADD     PC, R3, R5       ; and call

         Pull   "R2, r4"
         BL      ReleaseBuff      ; discard buffer got for GSTRANSing

1012
         MRS     R10, CPSR
Kevin Bracey's avatar
Kevin Bracey committed
1013
         ORR     R10, R10, #C_bit ; set C carefully
1014
         MSR     CPSR_f, R10
Neil Turton's avatar
Neil Turton committed
1015
         STRVS   R0, [stack]
Kevin Bracey's avatar
Kevin Bracey committed
1016
         Pull   "R0, R2-R10, pc"
Neil Turton's avatar
Neil Turton committed
1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082

; Return a command syntax error.  First issue Service_SyntaxError for translation
11
 [ International                  ; Internationalize syntax error messages
         Pull    "r4"             ; r4-> command string in module
         MOV     r1, #Service_SyntaxError ; r2->info block for command, r3->module
         BL      Issue_Service    ; Issue SyntaxError service for possible translation
         CMP     r1, #0           ; Service claimed?
         BEQ     unpleasantness_in_ModCommsLookUp ; Yes then r0-> error block

         Push    "r4"             ; Save -> command string
 ]

         LDR     r4, [r2, #4]
         MOV     r7, r2
         BL      GetOscliBuffer   ; get space for error
         MOV     R2, #ErrorNumber_BadNoParms
         STR     R2, [R5]
         LDR     R2, [R7, #8]
         CMP     R2, #0
         ADREQ   R0, %FT13        ; default error message
         ADDNE   R0, R2, R3       ; point at message
         ORREQ   r4, r4, #International_Help
         TST     r4, #International_Help
         ADREQL  r4, MOSdictionary
         BEQ     %FT37
         MOV     r7, r0
         SUB     sp, sp, #16
         LDR     r2, [r3, #-4]
         LDR     r0, [r3, #Module_MsgFile]
         TST     r0, #12,2
         CMPEQ   r0, #1
         CMPCS   r2, r0
         MOVLS   r0, #0
         BLS     %FT33
         ADD     r1, r3, r0
         MOV     r2, #0
         MOV     r0, sp
         SWI     XMessageTrans_OpenFile
         MOVVS   r0, #0
33       MOV     r1, r7
         MOV     r7, r0
         MOV     r2, #0
         SWI     XMessageTrans_Lookup
         ADDVS   r2, r0, #4
         SWI     XMessageTrans_Dictionary
         ADDVS   r2, r0, #4
         MOV     r4, r0
         MOV     r0, r2
         LDR     r2, [sp, #16]
         ADD     r1, r5, #4
         BL      expandsyntaxmessage
         MOVS    r0, r7
         SWINE   XMessageTrans_CloseFile
         ADD     sp, sp, #16
         Pull    r2
         B       %FT39
37
         Pull    r2
         ADD     r1, r5, #4
         BL      expandsyntaxmessage
39
         MOV     r0, r5

unpleasantness_in_ModCommsLookUp
         STR     R0, [stack]
1083
         MSR     CPSR_f, #V_bit+C_bit
Kevin Bracey's avatar
Kevin Bracey committed
1084
         Pull   "R0, R2-R10, PC"
Neil Turton's avatar
Neil Turton committed
1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128
13
         DCB     "NumParm", 0

        ALIGN

expandsyntaxmessage
         LDRB    R3, [R0], #1
         CMP     r3, #TokenEscapeChar
         BEQ     esm_tok
         STRB    R3, [R1], #1
         CMP     R3, #0
         BNE     expandsyntaxmessage
         SUB     r1, r1, #1
         MOV     pc, lr

esm_tok  LDRB    r3, [r0], #1
         Push   "r0, lr"
         CMP     r3, #0
         MOVEQ   r0, r2
         BEQ     esm001
         MOV     r0, r4
esmlp    SUBS    r3, r3, #1
         LDRNEB  r14, [r0]      ; ECN: Use R14 instead of R4 as using R4 corrupts
         ADDNE   r0, r0, r14    ; the dictionary pointer thus disallowing recusive tokens
         BNE     esmlp
         ADD     r0, r0, #1
esm001   BL      expandsyntaxmessage
         Pull   "r0, lr"
         B       expandsyntaxmessage

;---------------------------------------------------------------------------
; routine to just find a keyword in a table that has the flags specified.
; R0 points at command to find
; R1 points at module
; R2 offset of command table
; R4 word to EOR with flags : demand 0 result for match
; C set means allow messy matching, i.e. it's the system command table
; Uses R2-R5

; Return C set if found : R5 is execute offset, R3 length of string
; R2 is offset of execute offset of field found
; r4 is command pointer

FindItem ROUT
1129 1130
         Push   "R4, R6, R7"
         MRS     R7, CPSR         ; to remember C flag (32-bit clean)
Neil Turton's avatar
Neil Turton committed
1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147
         ADD     R2, R2, R1
         LDRB    R4, [R2]
         CMP     R4, #0
         BEQ     FindItem_EOTab
05       MOV     R3, #0           ; offset
01       LDRB    R4, [R0, R3]
         LDRB    R5, [R2, r3]
         CMP     R4, #&80         ; in table ?
         ADRCC   R6, Up_ItAndTerm_Check_Table
         LDRCCB  R4, [R6, R4]
         CMP     R4, #32
         CMPLE   R5, #32
         BLE     %FT04           ; matched, and we're at the terminator
         UpperCase R5, R6
         CMP     R4, R5
         ADDEQ   R3, R3, #1
         BEQ     %BT01
1148
         CMP     R4, #"."        ; success if abbreviation
Neil Turton's avatar
Neil Turton committed
1149
         BEQ     %FT02
1150
         TST     R7, #C_bit      ; C flag on entry
Neil Turton's avatar
Neil Turton committed
1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166
         BEQ     %FT07           ; nomatch
         CMP     R5, #32
         BGT     %FT07
         CMP     R4, #"A"
         RSBGES  R6, R4, #"Z"
         BLT     %FT04             ; matched, at terminator
07       LDRB    R5, [R2], #1
         CMP     R5, #32
         BGT     %BT07             ; skip to terminator
         ADD     R2, R2, #3
         BIC     R2, R2, #3        ; ALIGN
06       ADD     R2, R2, #16       ; !!! DEPENDANT ON TABLE FORMAT!!!
         LDRB    R5, [R2]
         CMP     R5, #0
         BNE     %BT05
FindItem_EOTab
1167
         Pull   "R4, R6, R7"
Kevin Bracey's avatar
Kevin Bracey committed
1168 1169
         CLC
         MOV     PC, lr            ; back with not found.
Neil Turton's avatar
Neil Turton committed
1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208

Up_ItAndTerm_Check_Table
; Table to uppercase and test for terminators for passed * commands
;      0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
   =   0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0     ; 0
   =   0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0     ; 1
   =   0 , "!", 0 , "#" , 0, 0, 0, "'", "(", ")", "*" , "+", 0 , "-", ".", "/"    ; 2
   =  "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", 0, ";", 0 , "=", 0 , "?"    ; 3
   =  "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O"    ; 4
   =  "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", 0, "]", 0, "_"    ; 5
   =  "`", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O"    ; 6
   =  "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "{", 0 , "}", "~", 0     ; 7

;  WHILE . < Up_ItAndTerm_Check_Table+256 ; top bit stuff done by CMP #&80
;   = . - Up_ItAndTerm_Check_Table
;  WEND                            ; entry for chars > 127 = char

02       CMP     R5, #32          ; only success if $R2 not terminated.
         BLE     %BT07
         ADD     R3, R3, #1       ; skip .
04       MOV     r6, r2
         ADD     r2, r2, r3
08       LDRB    R5, [R2], #1
         CMP     R5, #0
         BNE     %BT08            ; demand NULL terminator
         ADD     R2, R2, #3
         BIC     R2, R2, #3       ; ALIGN
         LDR     R5, [R2, #4]     ; get information word

         AND     R5, R5, #&C0000000 :AND::NOT:Help_Is_Code_Flag
                                  ; clear param numbers/low flags.
         LDR     R4, [stack]
         EORS    R5, R5, R4
         BNE     %BT06            ; flags don't match

         LDR     R5, [R2]         ; get Execute offset
         CMP     R5, #0
         BEQ     %BT06            ; not a command
         STR     r6, [stack]      ; return r4
1209
         Pull   "R4, R6, R7"
Neil Turton's avatar
Neil Turton committed
1210
         SUB     R2, R2, R1       ; get back to offset.
Kevin Bracey's avatar
Kevin Bracey committed
1211 1212
         SEC
         MOV     PC, lr
Neil Turton's avatar
Neil Turton committed
1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271

;****************************************************************************
; variegated routines
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

OscliInit
; circular buffer initialisation :
;  botUID := topUID := 0 ; currend := circbuffstart
; Redirection handles := 0
         MOV        R0, #0
         STR        R0, [R0, #OscliCBbotUID]
         STR        R0, [R0, #OscliCBtopUID]
         LDR        R1, =OscliCircBuffStart
         STR        R1, [R0, #OscliCBcurrend]
         STRB       R0, [R0, #RedirectInHandle]
         STRB       R0, [R0, #RedirectOutHandle]
         MOV        PC, R14

; buffer is valid if botUID < UID


; GetOscliBuffer used in module handler to get error buffers - saves workspace!

GetOscliBuffer ROUT
 ; return ptr in R5 to next buffer in Oscli's circular job
 ; UID in R6
 ; corrupts R2

; currend +:= 256
      MOV    R2, #0
      LDR    R5, [R2, #OscliCBcurrend]
      ADD    R5, R5, #OscliBuffSize

; IF currend >= circbufflimit
;  THEN currend := circbuffstart
      LDR    R6, =OscliCircBuffLimit
      CMP    R5, R6
      LDRHS  R5, =OscliCircBuffStart
      STR    R5, [R2, #OscliCBcurrend]

; topUID +:= 1
      LDR    R6, [R2, #OscliCBtopUID]
      ADD    R6, R6, #1
      STR    R6, [R2, #OscliCBtopUID]
; IF topUID > botUID + noBuffers
; THEN botUID +:= 1
      LDR    R5, [R2, #OscliCBbotUID]
      SUB    R2, R6, R5
      CMP    R2, #OscliNoBuffs
      MOV    R2, #0
      ADDGE  R5, R5, #1
      STRGE  R5, [R2, #OscliCBbotUID]

; RETURN currend, topUID
      LDR    R5, [R2, #OscliCBcurrend]
      MOV    PC, lr


ReleaseBuff ; take UID in R2, check whether can step back topUID
Kevin Bracey's avatar
Kevin Bracey committed
1272
     EntryS "R1-R4"
Neil Turton's avatar
Neil Turton committed
1273 1274 1275 1276 1277
     MOV    R1, #0
     LDR    R3, [R1, #OscliCBtopUID]
     LDR    R4, [R1, #OscliCBbotUID]
; IF UID = topUID AND topUID <> botUID
     CMP    R3, R4
Kevin Bracey's avatar
Kevin Bracey committed
1278
     EXITS  EQ
Neil Turton's avatar
Neil Turton committed
1279
     CMP    R2, R3
Kevin Bracey's avatar
Kevin Bracey committed
1280
     EXITS  NE
Neil Turton's avatar
Neil Turton committed
1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293
; THEN $(
;    topUID -:= 1
     SUB    R3, R3, #1
     STR    R3, [R1, #OscliCBtopUID]

;    IF currend = circbuffstart THEN currend := circbufflimit
     LDR    R3, [R1, #OscliCBcurrend]
     LDR    R4, =OscliCircBuffStart
     CMP    R3, R4
     LDREQ  R3, =OscliCircBuffLimit
; currend -:= 256
     SUB    R3, R3, #OscliBuffSize
     STR    R3, [R1, #OscliCBcurrend]
Kevin Bracey's avatar
Kevin Bracey committed
1294
     EXITS
Neil Turton's avatar
Neil Turton committed
1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325

        LTORG                   ; needed now not at top level

OscliRestoreFS
    Push    "R0, lr"
    MOV      R0, #FSControl_RestoreCurrent
    SWI      XOS_FSControl
    Pull    "R0, PC"

OscliTidy    ROUT  ; shut down redirection, restore permanent FS
     Push   "lr"
     BL      RemoveOscliCharJobs
     BL      OscliRestoreFS
     Pull   "PC"

RemoveOscliCharJobs ROUT
     Push   "R0-R2, lr"
     MOV     R0, #0
     LDRB    R1, [R0, #RedirectInHandle]
     CMP     R1, #0
     STRNEB  R0, [R0, #RedirectInHandle]
     SWINE   XOS_Find
     MOV     R0, #0 ; May have got error (discarded)
     LDRB    R1, [R0, #RedirectOutHandle]
     CMP     R1, #0
     STRNEB  R0, [R0, #RedirectOutHandle]
     SWINE   XOS_Find
     MOV     R2, #0
     MOV     R0, #WrchV
     ADR     R1, RedirectWrch
     SWI     XOS_Release
Kevin Bracey's avatar
Kevin Bracey committed
1326 1327
     CLRV
     Pull   "R0-R2, PC"
Neil Turton's avatar
Neil Turton committed
1328 1329

RedirectWrch ROUT
Kevin Bracey's avatar
Kevin Bracey committed
1330 1331
     Push   "R1, R2"
     SavePSR R2
Neil Turton's avatar
Neil Turton committed
1332 1333 1334
     MOV     R1, #0
     LDRB    R1, [R1, #RedirectOutHandle]
     SWI     XOS_BPut
Kevin Bracey's avatar
Kevin Bracey committed
1335 1336
     RestPSR R2                     ; VClear in entry psr
     Pull   "R1, R2, pc", VC
Neil Turton's avatar
Neil Turton committed
1337 1338 1339

RedirectError
     BL      RemoveOscliCharJobs
Kevin Bracey's avatar
Kevin Bracey committed
1340 1341 1342
     ORR     R2, R2, #V_bit
     RestPSR R2
     Pull   "R1, R2, pc"
Neil Turton's avatar
Neil Turton committed
1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423

; **************************************************************************
;
;       SWI OS_ChangeRedirection - Read/write redirection handles
;
; in:   R0 = new input  handle (0 => not redirected, -1 => leave alone)
;       R1 = new output handle (0 => not redirected, -1 => leave alone)
;
; out:  R0 = old input  handle (0 => not redirected)
;       R1 = old output handle (0 => not redirected)
;

ChangeRedirection ROUT
        MOV     R12, #0
        LDRB    R10, [R12, #RedirectInHandle]
        LDRB    R11, [R12, #RedirectOutHandle]

; do input handle

        CMP     R0, #&100               ; if out of range then just read
        BCS     %FT20

        STRB    R0, [R12, #RedirectInHandle]

20

; do output handle

        CMP     R1, #&100               ; if out of range then just read
        BCS     %FT40

        STRB    R1, [R12, #RedirectOutHandle]
        CMP     R1, #1                  ; CS <=> (R1 non-zero)
        TEQ     R11, #0                 ; NE <=> (R11 non-zero)
        BHI     %FT40                   ; [both non-zero, skip]

        BCS     %FT30                   ; [just R1 non-zero, so claim]
        BEQ     %FT40                   ; [both zero, skip]

; R11 non-zero, R1 zero, so release vector

        Push    "R0-R2, lr"             ; set up registers for claim or release
        MOV     R0, #WrchV
        ADR     R1, RedirectWrch
        MOV     R2, #0
        SWI     XOS_Release
        STRVS   R0, [sp, #0*4]
        Pull    "R0-R2, lr"
        ORRVS   lr, lr, #V_bit
        ExitSWIHandler VS
        B       %FT40

; R11 zero, R1 non-zero, so claim vector

30
        Push    "R0-R2, lr"
        MOV     R0, #WrchV
        ADR     R1, RedirectWrch
        MOV     R2, #0
        SWI     XOS_Claim
        STRVS   R0, [sp, #0*4]
        Pull    "R0-R2, lr"
        ORRVS   lr, lr, #V_bit
        ExitSWIHandler VS

40
        MOV     R0, R10
        MOV     R1, R11
        ExitSWIHandler

;**************************************************************************
; Module selection
;  Entered with V set if FileSwitch found a - : must get module or give error
;  R2 >= 0 if filing system selected: do nothing
;  R1 -> command prefix
;  Out: R1 updated
;    R2 = -1: no module
;    R2 = -<larger>:  R2 is selected module node
;         Selected prefix also preferred

CheckForModuleAsPrefix ROUT
Kevin Bracey's avatar
Kevin Bracey committed
1424
     EntryS "R0-R6"
Neil Turton's avatar
Neil Turton committed
1425 1426 1427 1428 1429 1430 1431 1432
     ADDVS   R1, R1, #1         ; skip -
     MOVVS   R2, #"-"
     BVS     %FT02
     CMP     R2, #-1
     BNE     %FT01
     MOV     R2, #":"           ; terminators for lookup

02   ADR     R5, %FT10
Kevin Bracey's avatar
Kevin Bracey committed
1433
     STR     R1, [stack, #Proc_RegOffset + 4]
Neil Turton's avatar
Neil Turton committed
1434 1435 1436 1437 1438 1439
03   LDRB    R3, [R1], #1
     UpperCase R3, R4
     LDRB    R4, [R5], #1
     CMP     R3, R4
     BEQ     %BT03
     CMP     R4, #0
Kevin Bracey's avatar
Kevin Bracey committed
1440
     LDRNE   R1, [stack, #Proc_RegOffset + 4]
Neil Turton's avatar
Neil Turton committed
1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469
     SUBEQ   R1, R1, #1
     MOV     R6, R1
     LDR     R1, =AliasExpansionBuffer
05   LDRB    R3, [R6], #1
     CMP     R3, #"."           ; disallow abbreviations: they're confusing!
     CMPNE   R3, #" "
     BLE     %FT01
     CMP     R3, R2
     STRNEB  R3, [R1], #1
     BNE     %BT05

     MOV     R3, #0
     STRB    R3, [R1]

     MOV     R0, #ModHandReason_LookupName
     LDR     R1, =AliasExpansionBuffer
     SWI     XOS_Module
     BVS     %FT01
     MOV     R2, R1
     LDR     R1, =AliasExpansionBuffer
     MOV     R0, #ModHandReason_MakePreferred
     SWI     XOS_Module

     MOV     R0, #Module_List
04   LDR     R0, [R0]
     SUBS    R2, R2, #1
     BPL     %BT04
     MOV     R1, R6                 ; point at rest of command line.
     RSB     R2, R0, #0
Kevin Bracey's avatar
Kevin Bracey committed
1470 1471 1472
     STR     R1, [stack, #Proc_RegOffset + 4]
     STR     R2, [stack, #Proc_RegOffset + 8]
     EXITS   VC
Neil Turton's avatar
Neil Turton committed
1473 1474

01
Kevin Bracey's avatar
Kevin Bracey committed
1475
     EXITS                           ; return fileswitch error if set
Neil Turton's avatar
Neil Turton committed
1476 1477 1478 1479
10
     =      "MODULE#",0
     ALIGN

1480 1481
     LTORG

Neil Turton's avatar
Neil Turton committed
1482
     END