Oscli 45.3 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 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

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"
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 363 364 365 366 367 368 369 370 371

  [ 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
372
      MOV    R2,#LongCLISize
373 374 375 376 377 378 379 380 381 382
      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
383
    [ International
Jeffrey Lee's avatar
Jeffrey Lee committed
384
      LDR    R3,=ZeroPage
Neil Turton's avatar
Neil Turton committed
385 386 387 388 389 390 391 392
      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.
393
      ADRL   R0, AliasStr
Neil Turton's avatar
Neil Turton committed
394 395
      SWI    XOS_ReadVarVal
      CMP    R2, #0         ; V always set anyway
Jeffrey Lee's avatar
Jeffrey Lee committed
396 397
   [ International
    [ ZeroPage = 0
Neil Turton's avatar
Neil Turton committed
398 399 400
      LDREQB R0,[R2,#ErrorSemaphore]
      ADDEQ  R0,R0,#1
      STREQB R0,[R2,#ErrorSemaphore]
Jeffrey Lee's avatar
Jeffrey Lee committed
401 402 403 404 405
    |
      LDREQ  R3,=ZeroPage
      LDREQB R0,[R3,#ErrorSemaphore]
      ADDEQ  R0,R0,#1
      STREQB R0,[R3,#ErrorSemaphore]
Neil Turton's avatar
Neil Turton committed
406
    ]
Jeffrey Lee's avatar
Jeffrey Lee committed
407
   ]
Neil Turton's avatar
Neil Turton committed
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
      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
438
      LDR   R4,=ZeroPage
Neil Turton's avatar
Neil Turton committed
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453
      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!
454
      MOV   R2, #LongCLISize
Neil Turton's avatar
Neil Turton committed
455 456 457
      MOV   R3, #0
      MOV   R4, #VarType_Expanded
      SWI   XOS_ReadVarVal
458 459 460
  [ Oscli_QuickAliases
oqa_quicksilvertime_alias
  ]
Neil Turton's avatar
Neil Turton committed
461 462 463 464 465 466 467 468 469 470
      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
471 472
      MOV    R5, #0
      SWI    XOS_SubstituteArgs32
Neil Turton's avatar
Neil Turton committed
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 518 519 520 521 522
      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

523 524 525
  [ Oscli_QuickAliases
AliasStr_QA = "ALIAS$", 0
  ]
Neil Turton's avatar
Neil Turton committed
526
AliasStr = "Alias$*", 0
527
AliasDot = "Alias$.", 0
Neil Turton's avatar
Neil Turton committed
528 529
      ALIGN

530 531 532
  [ Oscli_QuickAliases
oqa_quicksilvertime_noalias
  ]
Neil Turton's avatar
Neil Turton committed
533 534 535 536 537 538 539 540
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

541 542
  [ Oscli_HashedCommands
         BL        Oscli_cmd_hashsum            ; => hash value in r1
Jeffrey Lee's avatar
Jeffrey Lee committed
543
         LDR       r2,=ZeroPage
544
         STR       r1,[r2,#Oscli_CmdHashSum]
Jeffrey Lee's avatar
Jeffrey Lee committed
545 546 547
       [ ZeroPage <> 0
         MOV       r2,#0                        ; Must be zero for oscli_hlist_loop. Not entirely sure why!
       ]
548 549 550 551 552 553
         CMP       r1,#0
         BEQ       oscli_sysabbrevation
         BL        SysCommsHashedLookup
         B         oscli_syslook_done
oscli_sysabbrevation
  ]
Neil Turton's avatar
Neil Turton committed
554 555
         ADRL      R1, SysCommsModule
         MOV       R2, #SCHCTab-SysCommsModule
Kevin Bracey's avatar
Kevin Bracey committed
556
         SEC                                    ; carry set means sys module
Neil Turton's avatar
Neil Turton committed
557
         BL        ModCommsLookUp
558
oscli_syslook_done
Neil Turton's avatar
Neil Turton committed
559 560
         BCS       OscliExit

561 562 563
  [ Oscli_HashedCommands
         ;now try UtilityModule, if non-abbreviated command
         Push      "R2"
Jeffrey Lee's avatar
Jeffrey Lee committed
564
         LDR       r2,=ZeroPage
565 566 567 568 569 570 571 572
         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
Jeffrey Lee's avatar
Jeffrey Lee committed
573
         LDR       r2,=ZeroPage
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599
         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
600
         CLC
601 602 603 604 605 606 607 608
         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
609
; now try looking round the modules.
Jeffrey Lee's avatar
Jeffrey Lee committed
610
         LDR       R11, =ZeroPage+Module_List
Neil Turton's avatar
Neil Turton committed
611 612 613 614 615 616 617 618 619 620 621 622 623 624
         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
625
         CLC
Neil Turton's avatar
Neil Turton committed
626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643
         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
644
         CLC
Neil Turton's avatar
Neil Turton committed
645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661
         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
662
         CLC
Neil Turton's avatar
Neil Turton committed
663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688
         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
Robert Sprowson's avatar
Robert Sprowson committed
689
         MOV       R0, #FSControl_Run
Neil Turton's avatar
Neil Turton committed
690 691 692
71       SWI       XOS_FSControl
OscliExit
         Pull     "R2"
Kevin Bracey's avatar
Kevin Bracey committed
693 694
         SavePSR   R1
         Push     "R0"
Neil Turton's avatar
Neil Turton committed
695 696 697
         CMP       R2, #0                        ; -ve means no FS selected.
         MOVGE     R0, #FSControl_RestoreCurrent
         SWIGE     XOS_FSControl
Kevin Bracey's avatar
Kevin Bracey committed
698
         Pull     "R0"
Neil Turton's avatar
Neil Turton committed
699 700 701 702 703 704 705

         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
706 707 708 709 710 711 712
         BNE       %FT81
         CLRV
         Pull     "R0-R2, pc"
81
         SETV
         ADD       sp, sp, #4
         Pull     "R1-R2, pc"
Neil Turton's avatar
Neil Turton committed
713 714 715 716 717 718 719

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

07
         Push     "R0, R3-R6"
         MOV       R6, R0
720
         ADRL      R0, AliasDot
Neil Turton's avatar
Neil Turton committed
721 722 723 724 725 726 727 728 729
         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
730
         MOV       R0, #FSControl_Cat   ; *., skip .
Neil Turton's avatar
Neil Turton committed
731 732
         B         %BT71

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 792 793 794 795
;***************************************************************************

  [ 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
         ADRL   R2, SysCoHashedCmdTab
796
         AND    R4, R1,#Oscli_CHashValMask  ;hash value, masked for command hashing
797
         LDR    R2, [R2, R4, LSL #2]        ;command list for this hash value
798 799 800 801
         ADRL   R1, SysCommsModule
         CMP    R2, #1                      ;set carry if valid table entry
         BCS    ModCommsLookUp_AltEntry     ;note: carry set to indicate sys module
         Pull   "R0, R2-R10, pc"            ;bail if null hash table entry (with carry clear to indicate failure)
802 803 804 805
schl_fudge
         ADRL   R1, SysCommsModule
         ADRL   R2, SHC_fudgeulike
         SUB    R2, R2, R1                          ;fudge command list (offset)
Kevin Bracey's avatar
Kevin Bracey committed
806
         SEC                                        ;carry set means sys module
807 808 809 810 811 812
         B      ModCommsLookUp_AltEntry

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

814 815 816
UtilCommsHashedLookup ROUT
         Push   "R0, R2-R10, lr"
         ADRL   R2, UtilHashedCmdTab
817
         AND    R4, R1,#Oscli_CHashValMask  ;hash value, masked for command hashing
818
         LDR    R2, [R2, R4, LSL #2]        ;command list for this hash value
819 820 821 822
         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
823 824 825
;
  ] ;Oscli_HashedCommands

Neil Turton's avatar
Neil Turton committed
826 827 828 829 830 831 832 833 834 835 836 837 838 839
;***************************************************************************

; 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"
840 841 842
  [ Oscli_HashedCommands
ModCommsLookUp_AltEntry
  ]
Neil Turton's avatar
Neil Turton committed
843 844 845 846 847
         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
848 849 850 851
         BLCS    %FT05
         CLC                      ; clears C and V
         Pull   "R0, R2-R10, PC"
05
Neil Turton's avatar
Neil Turton committed
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
         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
916
         ADD     R6, R1, R2
Neil Turton's avatar
Neil Turton committed
917 918 919 920 921
nastycharscan
         LDRB    R2, [R1], #1
         CMP     R2, #&7F
         CMPNE   R2, #" "
         BLE     preversion_detectified
922 923
         CMP     R1, R6
         BLO     nastycharscan
Neil Turton's avatar
Neil Turton committed
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 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021

         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

1022
         MRS     R10, CPSR
Kevin Bracey's avatar
Kevin Bracey committed
1023
         ORR     R10, R10, #C_bit ; set C carefully
1024
         MSR     CPSR_f, R10
Neil Turton's avatar
Neil Turton committed
1025
         STRVS   R0, [stack]
Kevin Bracey's avatar
Kevin Bracey committed
1026
         Pull   "R0, R2-R10, pc"
Neil Turton's avatar
Neil Turton committed
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

; 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
1068
         MOV     r7, r0           ; Message file data block
Neil Turton's avatar
Neil Turton committed
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078
         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
1079
         MOVS    r0, r7           ; Close iff message file was used
Neil Turton's avatar
Neil Turton committed
1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092
         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]
1093
         MSR     CPSR_f, #V_bit+C_bit
Kevin Bracey's avatar
Kevin Bracey committed
1094
         Pull   "R0, R2-R10, PC"
Neil Turton's avatar
Neil Turton committed
1095 1096 1097
13
         DCB     "NumParm", 0

1098
         ALIGN
Neil Turton's avatar
Neil Turton committed
1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111

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"
1112
         CMP     r3, #Token0    ; Token0 => use R2
Neil Turton's avatar
Neil Turton committed
1113 1114 1115 1116 1117
         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
1118
         ADDNE   r0, r0, r14    ; the dictionary pointer thus disallowing recursive tokens
Neil Turton's avatar
Neil Turton committed
1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138
         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
1139 1140
         Push   "R4, R6, R7"
         MRS     R7, CPSR         ; to remember C flag (32-bit clean)
Neil Turton's avatar
Neil Turton committed
1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157
         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
1158
         CMP     R4, #"."        ; success if abbreviation
Neil Turton's avatar
Neil Turton committed
1159
         BEQ     %FT02
1160
         TST     R7, #C_bit      ; C flag on entry
Neil Turton's avatar
Neil Turton committed
1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176
         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
1177
         Pull   "R4, R6, R7"
Kevin Bracey's avatar
Kevin Bracey committed
1178 1179
         CLC
         MOV     PC, lr            ; back with not found.
Neil Turton's avatar
Neil Turton committed
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 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218

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
1219
         Pull   "R4, R6, R7"
Neil Turton's avatar
Neil Turton committed
1220
         SUB     R2, R2, R1       ; get back to offset.
Kevin Bracey's avatar
Kevin Bracey committed
1221 1222
         SEC
         MOV     PC, lr
Neil Turton's avatar
Neil Turton committed
1223 1224 1225 1226 1227 1228 1229 1230 1231

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

OscliInit
; circular buffer initialisation :
;  botUID := topUID := 0 ; currend := circbuffstart
; Redirection handles := 0
Jeffrey Lee's avatar
Jeffrey Lee committed
1232 1233
         LDR        R0, =ZeroPage
       [ ZeroPage = 0
Neil Turton's avatar
Neil Turton committed
1234 1235
         STR        R0, [R0, #OscliCBbotUID]
         STR        R0, [R0, #OscliCBtopUID]
Jeffrey Lee's avatar
Jeffrey Lee committed
1236 1237 1238 1239 1240
       |
         MOV        R1, #0
         STR        R1, [R0, #OscliCBbotUID]
         STR        R1, [R0, #OscliCBtopUID]
       ]
Neil Turton's avatar
Neil Turton committed
1241 1242
         LDR        R1, =OscliCircBuffStart
         STR        R1, [R0, #OscliCBcurrend]
Jeffrey Lee's avatar
Jeffrey Lee committed
1243
         ASSERT     (ZeroPage :AND: 255) = 0
Neil Turton's avatar
Neil Turton committed
1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258
         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
1259
      LDR    R2, =ZeroPage
Neil Turton's avatar
Neil Turton committed
1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278
      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
1279
      LDR    R2, =ZeroPage
Neil Turton's avatar
Neil Turton committed
1280 1281 1282 1283 1284 1285 1286 1287 1288
      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
1289
     EntryS "R1-R4"
Jeffrey Lee's avatar
Jeffrey Lee committed
1290
     LDR    R1, =ZeroPage
Neil Turton's avatar
Neil Turton committed
1291 1292 1293 1294
     LDR    R3, [R1, #OscliCBtopUID]
     LDR    R4, [R1, #OscliCBbotUID]
; IF UID = topUID AND topUID <> botUID
     CMP    R3, R4
Kevin Bracey's avatar
Kevin Bracey committed
1295
     EXITS  EQ
Neil Turton's avatar
Neil Turton committed
1296
     CMP    R2, R3
Kevin Bracey's avatar
Kevin Bracey committed
1297
     EXITS  NE
Neil Turton's avatar
Neil Turton committed
1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310
; 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
1311
     EXITS
Neil Turton's avatar
Neil Turton committed
1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328

        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"
Jeffrey Lee's avatar
Jeffrey Lee committed
1329
     LDR     R0, =ZeroPage
Neil Turton's avatar
Neil Turton committed
1330 1331
     LDRB    R1, [R0, #RedirectInHandle]
     CMP     R1, #0
Jeffrey Lee's avatar
Jeffrey Lee committed
1332
     ASSERT  (ZeroPage :AND: 255) = 0
Neil Turton's avatar
Neil Turton committed
1333
     STRNEB  R0, [R0, #RedirectInHandle]
Jeffrey Lee's avatar
Jeffrey Lee committed
1334 1335 1336
   [ ZeroPage <> 0
     MOV     R0, #0
   ]
Neil Turton's avatar
Neil Turton committed
1337
     SWINE   XOS_Find
Jeffrey Lee's avatar
Jeffrey Lee committed
1338
     LDR     R0, =ZeroPage ; May have got error (discarded)
Neil Turton's avatar
Neil Turton committed
1339 1340
     LDRB    R1, [R0, #RedirectOutHandle]
     CMP     R1, #0
Jeffrey Lee's avatar
Jeffrey Lee committed
1341
     ASSERT  (ZeroPage :AND: 255) = 0
Neil Turton's avatar
Neil Turton committed
1342
     STRNEB  R0, [R0, #RedirectOutHandle]
Jeffrey Lee's avatar
Jeffrey Lee committed
1343 1344 1345
   [ ZeroPage <> 0
     MOV     R0, #0 ; May have got error (discarded)
   ]
Neil Turton's avatar
Neil Turton committed
1346 1347 1348 1349 1350
     SWINE   XOS_Find
     MOV     R2, #0
     MOV     R0, #WrchV
     ADR     R1, RedirectWrch
     SWI     XOS_Release
Kevin Bracey's avatar
Kevin Bracey committed
1351 1352
     CLRV
     Pull   "R0-R2, PC"
Neil Turton's avatar
Neil Turton committed
1353 1354

RedirectWrch ROUT
Kevin Bracey's avatar
Kevin Bracey committed
1355 1356
     Push   "R1, R2"
     SavePSR R2
Jeffrey Lee's avatar
Jeffrey Lee committed
1357
     LDR     R1, =ZeroPage
Neil Turton's avatar
Neil Turton committed
1358 1359
     LDRB    R1, [R1, #RedirectOutHandle]
     SWI     XOS_BPut
Kevin Bracey's avatar
Kevin Bracey committed
1360 1361
     RestPSR R2                     ; VClear in entry psr
     Pull   "R1, R2, pc", VC
Neil Turton's avatar
Neil Turton committed
1362 1363 1364

RedirectError
     BL      RemoveOscliCharJobs
Kevin Bracey's avatar
Kevin Bracey committed
1365 1366 1367
     ORR     R2, R2, #V_bit
     RestPSR R2
     Pull   "R1, R2, pc"
Neil Turton's avatar
Neil Turton committed
1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380

; **************************************************************************
;
;       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
1381
        LDR     R12, =ZeroPage
Neil Turton's avatar
Neil Turton committed
1382 1383 1384 1385 1386 1387
        LDRB    R10, [R12, #RedirectInHandle]
        LDRB    R11, [R12, #RedirectOutHandle]

; do input handle

        CMP     R0, #&100               ; if out of range then just read
1388
        STRCCB  R0, [R12, #RedirectInHandle]
Neil Turton's avatar
Neil Turton committed
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 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444

; 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
1445
     EntryS "R0-R6"
Neil Turton's avatar
Neil Turton committed
1446 1447 1448 1449 1450 1451 1452 1453
     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
1454
     STR     R1, [stack, #Proc_RegOffset + 4]
Neil Turton's avatar
Neil Turton committed
1455 1456 1457 1458 1459 1460
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
1461
     LDRNE   R1, [stack, #Proc_RegOffset + 4]
Neil Turton's avatar
Neil Turton committed
1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484
     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
1485
     LDR     R0, =ZeroPage+Module_List
Neil Turton's avatar
Neil Turton committed
1486 1487 1488 1489 1490
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
1491 1492 1493
     STR     R1, [stack, #Proc_RegOffset + 4]
     STR     R2, [stack, #Proc_RegOffset + 8]
     EXITS   VC
Neil Turton's avatar
Neil Turton committed
1494 1495

01
Kevin Bracey's avatar
Kevin Bracey committed
1496
     EXITS                           ; return fileswitch error if set
Neil Turton's avatar
Neil Turton committed
1497 1498 1499 1500
10
     =      "MODULE#",0
     ALIGN

1501 1502
     LTORG

Neil Turton's avatar
Neil Turton committed
1503
     END