Oscli 43.8 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
        MACRO
$l      CheckUID $reg, $tmp
Jeffrey Lee's avatar
Jeffrey Lee committed
28
$l      LDR      $tmp, =ZeroPage
Neil Turton's avatar
Neil Turton committed
29 30 31 32 33 34 35 36 37 38 39 40 41 42
        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
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
Jeffrey Lee's avatar
Jeffrey Lee committed
57 58
           LDR     R0, =ZeroPage
           ASSERT  (ZeroPage :AND: 255) = 0
Neil Turton's avatar
Neil Turton committed
59 60 61 62 63
           CMP     R2, #&40
           LDREQB  R1, [R0, #RedirectInHandle]
           LDRNEB  R1, [R0, #RedirectOutHandle]
           STREQB  R0, [R0, #RedirectInHandle]
           STRNEB  R0, [R0, #RedirectOutHandle]
Jeffrey Lee's avatar
Jeffrey Lee committed
64 65 66
         [ ZeroPage <> 0
           MOV     R0, #0
         ]
Neil Turton's avatar
Neil Turton committed
67 68 69 70 71 72 73 74 75 76
           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
Jeffrey Lee's avatar
Jeffrey Lee committed
77
           LDR     R1, =ZeroPage
Neil Turton's avatar
Neil Turton committed
78
           STREQB  R0, [R1, #RedirectInHandle]
Kevin Bracey's avatar
Kevin Bracey committed
79
           BEQ     %FT00
Neil Turton's avatar
Neil Turton committed
80 81 82 83 84 85 86 87
           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
88
           LDR     R2, [stack, #Proc_RegOffset]
Neil Turton's avatar
Neil Turton committed
89
           CMP     R2, #&C0
Kevin Bracey's avatar
Kevin Bracey committed
90
           EXITS   NE
Neil Turton's avatar
Neil Turton committed
91 92 93

; >> file, so move to EOF

Jeffrey Lee's avatar
Jeffrey Lee committed
94
           LDR     R1, =ZeroPage
Neil Turton's avatar
Neil Turton committed
95 96 97 98 99
           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
100
           EXITS   VC
Neil Turton's avatar
Neil Turton committed
101 102 103 104 105 106 107 108 109 110

           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
111
           EXITVS
Neil Turton's avatar
Neil Turton committed
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 148 149 150


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
151 152
       |
         SETV                           ; In place of TranslateError
Neil Turton's avatar
Neil Turton committed
153
       ]
Kevin Bracey's avatar
Kevin Bracey committed
154
         Pull      "pc"
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

; now check for redirection.
; Redirection setter ::= "{ " [ >= 1 Redirection spec] "}"
; where
; Redirection spec ::=  "> "filename" " | "< "filename" " | ">> "filename" "
188
; Also check terminator in first LongCLISize chars.
Neil Turton's avatar
Neil Turton committed
189 190
         SUB        R11, R0, #1
         MOV        R1, #0
191
         ADD        R2, R0, #LongCLISize
Neil Turton's avatar
Neil Turton committed
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
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
Robert Sprowson's avatar
Robert Sprowson committed
254 255
       |
         SETV
Neil Turton's avatar
Neil Turton committed
256 257 258 259 260 261 262
       ]
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
263 264
         SETV
         Pull     "R0-R2, PC"
Neil Turton's avatar
Neil Turton committed
265 266 267 268 269 270 271 272 273 274 275 276 277 278

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

279
         SUB       R10, R0, #1
Neil Turton's avatar
Neil Turton committed
280 281 282 283 284 285 286 287 288 289 290 291 292 293
; 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
294
         BNE       DoFSCV_RunR10
Neil Turton's avatar
Neil Turton committed
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

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"
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362

  [ 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
363
      MOV    R2,#LongCLISize
364 365 366 367 368 369 370 371 372 373
      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
374
    [ International
Jeffrey Lee's avatar
Jeffrey Lee committed
375
      LDR    R3,=ZeroPage
Neil Turton's avatar
Neil Turton committed
376 377 378 379 380 381 382 383
      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.
384
      ADRL   R0, AliasStr
Neil Turton's avatar
Neil Turton committed
385 386
      SWI    XOS_ReadVarVal
      CMP    R2, #0         ; V always set anyway
Jeffrey Lee's avatar
Jeffrey Lee committed
387 388
   [ International
    [ ZeroPage = 0
Neil Turton's avatar
Neil Turton committed
389 390 391
      LDREQB R0,[R2,#ErrorSemaphore]
      ADDEQ  R0,R0,#1
      STREQB R0,[R2,#ErrorSemaphore]
Jeffrey Lee's avatar
Jeffrey Lee committed
392 393 394 395 396
    |
      LDREQ  R3,=ZeroPage
      LDREQB R0,[R3,#ErrorSemaphore]
      ADDEQ  R0,R0,#1
      STREQB R0,[R3,#ErrorSemaphore]
Neil Turton's avatar
Neil Turton committed
397
    ]
Jeffrey Lee's avatar
Jeffrey Lee committed
398
   ]
Neil Turton's avatar
Neil Turton committed
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
      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
Jeffrey Lee's avatar
Jeffrey Lee committed
429
      LDR   R4,=ZeroPage
Neil Turton's avatar
Neil Turton committed
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444
      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!
445
      MOV   R2, #LongCLISize
Neil Turton's avatar
Neil Turton committed
446 447 448
      MOV   R3, #0
      MOV   R4, #VarType_Expanded
      SWI   XOS_ReadVarVal
449 450 451
  [ Oscli_QuickAliases
oqa_quicksilvertime_alias
  ]
Neil Turton's avatar
Neil Turton committed
452 453 454 455 456 457 458 459 460 461
      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
Kevin Bracey's avatar
Kevin Bracey committed
462 463
      MOV    R5, #0
      SWI    XOS_SubstituteArgs32
Neil Turton's avatar
Neil Turton committed
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
      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

514 515 516
  [ Oscli_QuickAliases
AliasStr_QA = "ALIAS$", 0
  ]
Neil Turton's avatar
Neil Turton committed
517
AliasStr = "Alias$*", 0
518
AliasDot = "Alias$.", 0
Neil Turton's avatar
Neil Turton committed
519 520
      ALIGN

521 522 523
  [ Oscli_QuickAliases
oqa_quicksilvertime_noalias
  ]
Neil Turton's avatar
Neil Turton committed
524 525 526 527 528 529 530 531
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

532 533
  [ Oscli_HashedCommands
         BL        Oscli_cmd_hashsum            ; => hash value in r1
Jeffrey Lee's avatar
Jeffrey Lee committed
534
         LDR       r2,=ZeroPage
535
         STR       r1,[r2,#Oscli_CmdHashSum]
Jeffrey Lee's avatar
Jeffrey Lee committed
536 537 538
       [ ZeroPage <> 0
         MOV       r2,#0                        ; Must be zero for oscli_hlist_loop. Not entirely sure why!
       ]
539
         CMP       r1,#0
540
         BEQ       oscli_abbreviation
541
         BL        SysCommsHashedLookup
Neil Turton's avatar
Neil Turton committed
542 543
         BCS       OscliExit

544 545
         Push      "R2"
         ;now try list of modules on hash value
Jeffrey Lee's avatar
Jeffrey Lee committed
546
         LDR       r2,=ZeroPage
547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572
         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
573
         CLC
574 575 576 577 578
         BL        ModCommsLookUp
         BCC       oscli_hlist_loop
         Pull      "r3,r4"
         ADD       stack,stack,#4
         B         OscliExit
579
oscli_abbreviation
580 581
  ] ;Oscli_HashedCommands

Neil Turton's avatar
Neil Turton committed
582
; now try looking round the modules.
Jeffrey Lee's avatar
Jeffrey Lee committed
583
         LDR       R11, =ZeroPage+Module_List
Neil Turton's avatar
Neil Turton committed
584 585 586 587 588 589 590 591 592 593 594 595 596 597
         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
598
         CLC
Neil Turton's avatar
Neil Turton committed
599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616
         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
617
         CLC
Neil Turton's avatar
Neil Turton committed
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634
         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
635
         CLC
Neil Turton's avatar
Neil Turton committed
636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658
         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

659 660
DoFSCV_RunR10
         MOV       R0, R10
Neil Turton's avatar
Neil Turton committed
661 662 663
UKCNotClaimed
         MOV       R1, R0
DoFSCV_Run
Robert Sprowson's avatar
Robert Sprowson committed
664
         MOV       R0, #FSControl_Run
Neil Turton's avatar
Neil Turton committed
665 666 667
71       SWI       XOS_FSControl
OscliExit
         Pull     "R2"
Kevin Bracey's avatar
Kevin Bracey committed
668 669
         SavePSR   R1
         Push     "R0"
Neil Turton's avatar
Neil Turton committed
670 671 672
         CMP       R2, #0                        ; -ve means no FS selected.
         MOVGE     R0, #FSControl_RestoreCurrent
         SWIGE     XOS_FSControl
Kevin Bracey's avatar
Kevin Bracey committed
673
         Pull     "R0"
Neil Turton's avatar
Neil Turton committed
674 675 676 677 678 679 680

         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
681 682 683 684 685 686 687
         BNE       %FT81
         CLRV
         Pull     "R0-R2, pc"
81
         SETV
         ADD       sp, sp, #4
         Pull     "R1-R2, pc"
Neil Turton's avatar
Neil Turton committed
688 689 690 691 692 693 694

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

07
         Push     "R0, R3-R6"
         MOV       R6, R0
695
         ADRL      R0, AliasDot
Neil Turton's avatar
Neil Turton committed
696 697 698 699 700 701 702 703 704
         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
Robert Sprowson's avatar
Robert Sprowson committed
705
         MOV       R0, #FSControl_Cat   ; *., skip .
Neil Turton's avatar
Neil Turton committed
706 707
         B         %BT71

708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744
;***************************************************************************

  [ 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"
;
745
;special entry of ModCommsLookUp, for hashed lookup of fudged commands
746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769
;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
770
         ADRL   R2, UtilHashedCmdTab
771
         AND    R4, R1,#Oscli_CHashValMask  ;hash value, masked for command hashing
772
         LDR    R2, [R2, R4, LSL #2]        ;command list for this hash value
773 774 775 776
         ADRL   R1, UtilityMod
         TEQ    R2, #0,2                    ;check R2 and clear carry
         BNE    ModCommsLookUp_AltEntry
         Pull   "R0, R2-R10, pc"            ;bail if null hash table entry
777
schl_fudge
778
         ADRL   R1, UtilityMod
779 780
         ADRL   R2, SHC_fudgeulike
         SUB    R2, R2, R1                          ;fudge command list (offset)
Kevin Bracey's avatar
Kevin Bracey committed
781
         SEC                                        ;carry set means sys module
782 783 784 785
         B      ModCommsLookUp_AltEntry

  ] ;Oscli_HashedCommands

Neil Turton's avatar
Neil Turton committed
786 787 788 789 790 791 792 793 794 795 796 797 798 799
;***************************************************************************

; 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"
800 801 802
  [ Oscli_HashedCommands
ModCommsLookUp_AltEntry
  ]
Neil Turton's avatar
Neil Turton committed
803 804 805 806 807
         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
808 809 810 811
         BLCS    %FT05
         CLC                      ; clears C and V
         Pull   "R0, R2-R10, PC"
05
Neil Turton's avatar
Neil Turton committed
812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 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
         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
876
         ADD     R6, R1, R2
Neil Turton's avatar
Neil Turton committed
877 878 879 880 881
nastycharscan
         LDRB    R2, [R1], #1
         CMP     R2, #&7F
         CMPNE   R2, #" "
         BLE     preversion_detectified
882 883
         CMP     R1, R6
         BLO     nastycharscan
Neil Turton's avatar
Neil Turton committed
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

         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

982
         MRS     R10, CPSR
Kevin Bracey's avatar
Kevin Bracey committed
983
         ORR     R10, R10, #C_bit ; set C carefully
984
         MSR     CPSR_f, R10
Neil Turton's avatar
Neil Turton committed
985
         STRVS   R0, [stack]
Kevin Bracey's avatar
Kevin Bracey committed
986
         Pull   "R0, R2-R10, pc"
Neil Turton's avatar
Neil Turton committed
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 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027

; 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
1028
         MOV     r7, r0           ; Message file data block
Neil Turton's avatar
Neil Turton committed
1029 1030 1031 1032 1033 1034 1035 1036 1037 1038
         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
1039
         MOVS    r0, r7           ; Close iff message file was used
Neil Turton's avatar
Neil Turton committed
1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052
         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]
1053
         MSR     CPSR_f, #V_bit+C_bit
Kevin Bracey's avatar
Kevin Bracey committed
1054
         Pull   "R0, R2-R10, PC"
Neil Turton's avatar
Neil Turton committed
1055 1056 1057
13
         DCB     "NumParm", 0

1058
         ALIGN
Neil Turton's avatar
Neil Turton committed
1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071

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"
1072
         CMP     r3, #Token0    ; Token0 => use R2
Neil Turton's avatar
Neil Turton committed
1073 1074 1075 1076 1077
         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
1078
         ADDNE   r0, r0, r14    ; the dictionary pointer thus disallowing recursive tokens
Neil Turton's avatar
Neil Turton committed
1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098
         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
1099 1100
         Push   "R4, R6, R7"
         MRS     R7, CPSR         ; to remember C flag (32-bit clean)
Neil Turton's avatar
Neil Turton committed
1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117
         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
1118
         CMP     R4, #"."        ; success if abbreviation
Neil Turton's avatar
Neil Turton committed
1119
         BEQ     %FT02
1120
         TST     R7, #C_bit      ; C flag on entry
Neil Turton's avatar
Neil Turton committed
1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136
         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
1137
         Pull   "R4, R6, R7"
Kevin Bracey's avatar
Kevin Bracey committed
1138 1139
         CLC
         MOV     PC, lr            ; back with not found.
Neil Turton's avatar
Neil Turton committed
1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178

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
1179
         Pull   "R4, R6, R7"
Neil Turton's avatar
Neil Turton committed
1180
         SUB     R2, R2, R1       ; get back to offset.
Kevin Bracey's avatar
Kevin Bracey committed
1181 1182
         SEC
         MOV     PC, lr
Neil Turton's avatar
Neil Turton committed
1183 1184 1185 1186 1187 1188 1189 1190 1191

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

OscliInit
; circular buffer initialisation :
;  botUID := topUID := 0 ; currend := circbuffstart
; Redirection handles := 0
Jeffrey Lee's avatar
Jeffrey Lee committed
1192 1193
         LDR        R0, =ZeroPage
       [ ZeroPage = 0
Neil Turton's avatar
Neil Turton committed
1194 1195
         STR        R0, [R0, #OscliCBbotUID]
         STR        R0, [R0, #OscliCBtopUID]
Jeffrey Lee's avatar
Jeffrey Lee committed
1196 1197 1198 1199 1200
       |
         MOV        R1, #0
         STR        R1, [R0, #OscliCBbotUID]
         STR        R1, [R0, #OscliCBtopUID]
       ]
Neil Turton's avatar
Neil Turton committed
1201 1202
         LDR        R1, =OscliCircBuffStart
         STR        R1, [R0, #OscliCBcurrend]
Jeffrey Lee's avatar
Jeffrey Lee committed
1203
         ASSERT     (ZeroPage :AND: 255) = 0
Neil Turton's avatar
Neil Turton committed
1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218
         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
Jeffrey Lee's avatar
Jeffrey Lee committed
1219
      LDR    R2, =ZeroPage
Neil Turton's avatar
Neil Turton committed
1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238
      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
Jeffrey Lee's avatar
Jeffrey Lee committed
1239
      LDR    R2, =ZeroPage
Neil Turton's avatar
Neil Turton committed
1240 1241 1242 1243 1244 1245 1246 1247 1248
      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
1249
     EntryS "R1-R4"
Jeffrey Lee's avatar
Jeffrey Lee committed
1250
     LDR    R1, =ZeroPage
Neil Turton's avatar
Neil Turton committed
1251 1252 1253 1254
     LDR    R3, [R1, #OscliCBtopUID]
     LDR    R4, [R1, #OscliCBbotUID]
; IF UID = topUID AND topUID <> botUID
     CMP    R3, R4
Kevin Bracey's avatar
Kevin Bracey committed
1255
     EXITS  EQ
Neil Turton's avatar
Neil Turton committed
1256
     CMP    R2, R3
Kevin Bracey's avatar
Kevin Bracey committed
1257
     EXITS  NE
Neil Turton's avatar
Neil Turton committed
1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270
; 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
1271
     EXITS
Neil Turton's avatar
Neil Turton committed
1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288

        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"
1289 1290 1291 1292 1293 1294 1295 1296 1297
     ; Release WrchV before attempting to close the file handles. This protects
     ; against output going missing if it happens during the close operation(s)
     ; E.g. if we're running in a task window and the output device uses
     ; OS_UpCall 6, our WrchV hook may be left installed when control is
     ; returned to the Wimp: https://www.riscosopen.org/tracker/tickets/420
     MOV     R2, #0
     MOV     R0, #WrchV
     ADR     R1, RedirectWrch
     SWI     XOS_Release
Jeffrey Lee's avatar
Jeffrey Lee committed
1298
   [ ZeroPage <> 0
1299
     LDR     R2, =ZeroPage
Jeffrey Lee's avatar
Jeffrey Lee committed
1300
   ]
1301 1302 1303 1304
     LDRB    R1, [R2, #RedirectInHandle]
     CMP     R1, #0
     MOVNE   R0, #0
     STRNEB  R0, [R2, #RedirectInHandle]
Neil Turton's avatar
Neil Turton committed
1305
     SWINE   XOS_Find
1306
     LDRB    R1, [R2, #RedirectOutHandle]
Neil Turton's avatar
Neil Turton committed
1307
     CMP     R1, #0
1308 1309
     MOVNE   R0, #0 ; May have got error (discarded)
     STRNEB  R0, [R2, #RedirectOutHandle]
Neil Turton's avatar
Neil Turton committed
1310
     SWINE   XOS_Find
Kevin Bracey's avatar
Kevin Bracey committed
1311 1312
     CLRV
     Pull   "R0-R2, PC"
Neil Turton's avatar
Neil Turton committed
1313 1314

RedirectWrch ROUT
1315
     Push   "R1"
Jeffrey Lee's avatar
Jeffrey Lee committed
1316
     LDR     R1, =ZeroPage
Neil Turton's avatar
Neil Turton committed
1317 1318
     LDRB    R1, [R1, #RedirectOutHandle]
     SWI     XOS_BPut
1319
     Pull   "R1, pc", VC
Neil Turton's avatar
Neil Turton committed
1320
     BL      RemoveOscliCharJobs
1321 1322
     SETV
     Pull   "R1, pc"
Neil Turton's avatar
Neil Turton committed
1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335

; **************************************************************************
;
;       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
Jeffrey Lee's avatar
Jeffrey Lee committed
1336
        LDR     R12, =ZeroPage
Neil Turton's avatar
Neil Turton committed
1337 1338 1339 1340 1341 1342
        LDRB    R10, [R12, #RedirectInHandle]
        LDRB    R11, [R12, #RedirectOutHandle]

; do input handle

        CMP     R0, #&100               ; if out of range then just read
1343
        STRCCB  R0, [R12, #RedirectInHandle]
Neil Turton's avatar
Neil Turton committed
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

; 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
1400
     EntryS "R0-R6"
Neil Turton's avatar
Neil Turton committed
1401 1402 1403 1404 1405 1406 1407 1408
     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
1409
     STR     R1, [stack, #Proc_RegOffset + 4]
Neil Turton's avatar
Neil Turton committed
1410 1411 1412 1413 1414 1415
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
1416
     LDRNE   R1, [stack, #Proc_RegOffset + 4]
Neil Turton's avatar
Neil Turton committed
1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439
     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

Jeffrey Lee's avatar
Jeffrey Lee committed
1440
     LDR     R0, =ZeroPage+Module_List
Neil Turton's avatar
Neil Turton committed
1441 1442 1443 1444 1445
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
1446 1447 1448
     STR     R1, [stack, #Proc_RegOffset + 4]
     STR     R2, [stack, #Proc_RegOffset + 8]
     EXITS   VC
Neil Turton's avatar
Neil Turton committed
1449 1450

01
Kevin Bracey's avatar
Kevin Bracey committed
1451
     EXITS                           ; return fileswitch error if set
Neil Turton's avatar
Neil Turton committed
1452 1453 1454 1455
10
     =      "MODULE#",0
     ALIGN

1456 1457
     LTORG

Neil Turton's avatar
Neil Turton committed
1458
     END