MoreSWIs 34.1 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 17 18 19 20
; 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     => MoreSWIs

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;  SubstituteArgs
;    in:  R0 -> arglist (space delimited args, terminated by 10,13,0)
;         R1 -> buffer
Kevin Bracey's avatar
Kevin Bracey committed
21
;         R2 =  bufflen
Neil Turton's avatar
Neil Turton committed
22 23 24 25
;         R3 -> string to mangle
;         R4 =  no of chars in $R3
;    out: R2 =  no of chars in buffer

Kevin Bracey's avatar
Kevin Bracey committed
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
XOS_SubstituteArgs_code
        Push    "r5,lr"
        MOV     r5, #0
        SWI     XOS_SubstituteArgs32
        Pull    "r5,lr"
        B       SLVK_TestV

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;  SubstituteArgs32
;    in:  R0 -> arglist (space delimited args, terminated by 10,13,0)
;         R1 -> buffer
;         R2 =  bufflen
;         R3 -> string to mangle
;         R4 =  no of chars in $R3
;         R5 = flags
;               top bit set => don't append unused part of line
;    out: R2 =  no of chars in buffer
43

Kevin Bracey's avatar
Kevin Bracey committed
44
XOS_SubstituteArgs32_code ROUT
Neil Turton's avatar
Neil Turton committed
45

Kevin Bracey's avatar
Kevin Bracey committed
46
      WritePSRc SVC_mode, R12   ; enable IRQs
47
      NOP
Neil Turton's avatar
Neil Turton committed
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
      Push   "R0-R8, lr"
      ADD     R8, R4, R3

; try and get parameter positions.
; Items starting with " can have spaces in

      MOV   R6, #0       ; parameter number
      LDR   R12, =MacExStartPtrs
      LDR   R4, =MacExEndPtrs
35    LDRB  R5, [R0], #1
      CMP   R5, #" "
      BEQ   %BT35
      MOV   R2, #" "
      CMP   R5, #""""
      MOVEQ R2, #""""       ; quoted param
      CMP   r6, #10         ; "rest of line" item?
      MOVEQ r2, #-1         ; terminate on EOL only
      SUB   R0, R0, #1
      STR   R0, [R12, R6, LSL #2]
      CMP   r5, #""""
      ADDEQ R0, R0, #1
36    LDRB  R5, [R0], #1
      BL    suba_chktrm
      CMPNE R5, R2
      BNE   %BT36
      CMP   R5, #""""
      LDREQB R5, [R0]
      CMPEQ R5, #""""   ; check for "" in string
      ADDEQ R0, R0, #1
      BEQ   %BT36
      CMP   R2, #""""
      SUBNE R0, R0, #1
      STR   R0, [R4, R6, LSL #2]
      ADD   R6, R6, #1
      CMP   R6, #11           ; Parameters 0-9 and a "rest" set.
      BNE   %BT35

; Keep track of highest param used, so can tack any unused stuff on end.
; R3 points at string to get chars from
; R12 at start ptrs
; R4 at end ptrs

      MOV    R6, #0          ; count.
      MOV    R7, #0          ; highest param used.
Kevin Bracey's avatar
Kevin Bracey committed
92
      LDR    R2, [stack, #4*2]
Neil Turton's avatar
Neil Turton committed
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
37    BL     suba_getchar
      BEQ    %FT41
      CMP    R5, #"%"
      BEQ    %FT44
38    BL     suba_addchar
      B      %BT37

PCnotparm
      ADD    R5, R5, #"0"
      MOV    R11, R5
      MOV    R5, #"%"
      BL     suba_addchar
      MOV    R5, R11
      B      %BT38

44    BL     suba_getchar
      MOVEQ  R5, #"%"
      BEQ    %FT40
      CMP    R5, #"%"
      BEQ    %BT38
      CMP    R5, #"*"
      BEQ    DoStarParams
      SUBS   R5, R5, #"0"
      BMI    PCnotparm
      CMP    R5, #9
      BGT    PCnotparm

; itsa parameter! Get ptrs from R12, R4
      CMP    R5, R7
      ADDGE  R7, R5, #1
      LDR    R11, [R4, R5, LSL #2]
CopyToR11FromParamR5
      LDR    R10, [R12, R5, LSL #2]  ; start ptr
39    LDRB   R5, [R10], #1
      CMP    R10, R11
      BGT    %BT37
      BL     suba_addchar
      B      %BT39

DoStarParams ; had %* : find limits to copy between
      BL     suba_getchar
      BEQ    PCStarTerminates
      SUBS   R5, R5, #"0"
      BMI    PCStarNoDigit
      CMP    R5, #9
      MOVLE  R7, #11                  ; flag * used
      LDRLE  R11, [R4, #10*4]         ; always to EOL
      BLE    CopyToR11FromParamR5
PCStarNoDigit
      ADD    R5, R5, #"0"
      MOV    R11, R5
      MOV    R5, #"%"
      BL     suba_addchar
      MOV    R5, #"*"
      BL     suba_addchar
      MOV    R5, R11
      B      %BT38

PCStarTerminates
      MOV    R5, #"%"
      BL     suba_addchar
      MOV    R5, #"*"
40    BL     suba_addchar
41    CMP    r7, #11
      LDREQ  r12, [r4, #10*4]        ; no more to copy
      BEQ    %FT42
Kevin Bracey's avatar
Kevin Bracey committed
159 160 161 162
      LDR    r0, [stack, #4*5]
      CMP    r0, #0
      LDRPL  R12, [R12, R7, LSL #2]  ; ptr to rest of command line : copy
      LDRMI  r12, [r4, #10*4]        ; caller wants no appending.
Neil Turton's avatar
Neil Turton committed
163 164 165 166 167 168 169 170 171 172
42    LDRB   R5, [R12], #1
      BL     suba_addchar
      BL     suba_chktrm
      BNE    %BT42

      STR    R6, [stack, #4*2]
      Pull  "R0-R8, lr"
      ExitSWIHandler

suba_addchar
Kevin Bracey's avatar
Kevin Bracey committed
173
      EntryS
Neil Turton's avatar
Neil Turton committed
174 175 176
      ADD    R6, R6, #1
      CMP    R6, R2
      STRNEB R5, [R1], #1
Kevin Bracey's avatar
Kevin Bracey committed
177 178 179
      EXITS  NE

      PullEnv
Neil Turton's avatar
Neil Turton committed
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199

      ADRL   R0, ErrorBlock_BuffOverflow
    [ International
      BL     TranslateError
    ]
      STR    R0, [stack]
      Pull  "R0-R8, lr"
      B     SLVK_SetV

suba_getchar
      CMP    R3, R8
      LDRNEB R5, [R3], #1
      MOV    PC, lr

suba_chktrm
      CMP   R5, #13
      CMPNE R5, #10
      CMPNE R5, #0
      MOV   PC, lr

Kevin Bracey's avatar
Kevin Bracey committed
200 201
      LTORG

Neil Turton's avatar
Neil Turton committed
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Take R0 as pointer to null-terminated string, print it
; with line breaks before words that won't fit on the current line.
; CR forces a newline. TAB=tab to next column of 8. CHR$31 = hard space
; <27,n> => substitute nth dictionary entry:
;  dictionary is pointed at by r1, consists of a list of null-terminated
;  strings, with preceding length bytes.
; 0th dictentry => use string at r2.

XOS_PrettyPrint_code ROUT

; Inside here, r1 is the current string pointer
;              R3 is the linelength to format to
;              R4 is the current position in the line.
;              r6 is the return addr in word counting
;              r7 is the r1 restore value in reading word length
;              r8 is used in dictionary selection in getbytepp
;              r9 is the stack restoration level for exiting.
;              r11 is the dictionary pointer (0 means use MOS dict)
;              r12 is the special token pointer

Kevin Bracey's avatar
Kevin Bracey committed
223
          WritePSRc SVC_mode, r11
Neil Turton's avatar
Neil Turton committed
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239

          Push   "r0-r9, lr"

          BL      ReadWindowWidth    ; read linelength
          MOV     R3, R0
          MOV     R0, #165           ; read output cursor
          SWI     XOS_Byte
          ORR     R4, R1, #&80000000 ; no leading space even if in line.
          LDMFD   stack, {r1, r11, r12}   ; reload strptr, dictptr, tokptr
          CMP     r11, #0
          ADREQL  r11, MOSdictionary
          MOV     r9, stack

; loop over all words
01        BL      getwordlength
          CMP     R2, #0
Kevin Bracey's avatar
Kevin Bracey committed
240 241 242 243
          BNE     %FT03
          BL      getbytepp
          B       %FT21                ; null word - test for done
03
Neil Turton's avatar
Neil Turton committed
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 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 338 339 340 341 342 343 344
          CMP     R4, #0
          ADDGT   R2, R2, #1           ; allow for separator
          ADD     R0, R2, R4
          BIC     R0, R0, #&80000000   ; clear R4 flag
          CMP     R0, R3
          BLE     %FT10
          CMP     R4, #0
          SUBGT   R2, R2, #1          ; remove leading space length
          MOV     R4, #0              ; if word too long to fit, do newline
          SWI     XOS_NewLine
          BVS     exitpp

10        CMP     R4, #0
          BIC     R4, R4, #&80000000  ; clear "no leading space" flag
          ADD     R4, R4, R2
          SUBGT   R2, R2, #1
          SWIGT   XOS_WriteI+" "    ; output separator if not 1st on line
          BVS     exitpp

04        BL      getbytepp
          CMP     R0, #31           ; hard space?
          MOVEQ   R0, #" "
          SWI     XOS_WriteC
          BVS     exitpp
          SUBS    R2, R2, #1
          BNE     %BT04

21        CMP     R0, #13
          MOVEQ   R4, #0
          SWIEQ   XOS_NewLine
          BVS     exitpp

          CMP     R0, #TAB
          BEQ     %FT20
          CMP     R0, #0
          BNE     %BT01

exitpp    MOV     stack, r9
          STRVS   r0, [stack]
          Pull   "r0-r9,lr"
          B      SLVK_TestV

; TAB had: align to next multiple of 8
20        BIC     R4, R4, #&80000000
   ; first want to get next word length, to see if it's worth doing
          ADD     R5, R4, #8
          BIC     R5, R5, #7
          SUB     R5, R5, R4           ; spaces for this tab

24        BL      getwordlength
          CMP     R2, #0
          BNE     %FT23              ; got the word
          BL      getbytepp
          CMP     R0, #13
          BEQ     %BT21              ; TAB, CR - whalley!
          CMP     R0, #TAB
          SUBNE   R5, R5, #1         ; leading spaces, junk ignored
          ADDEQ   R5, R5, #8         ; multiple tabs OK tho.
          CMP     r0, #0             ; terminator?
          BNE     %BT24              ; only case to allow zero-length word
          SUB     r1, r1, #1         ; we know this rewinds OK

23        ADD     R0, R4, R5
          ADD     R0, R0, R2
          CMP     R0, R3
          MOVGT   R0, #13           ; next tab stop too far : newline
          BGT     %BT21
22        SWI     XOS_WriteI+" "
          BVS     exitpp
          ADD     R4, R4, #1
          SUBS    r5, r5, #1
          BNE     %BT22
          ORR     R4, R4, #&80000000 ; set top bit to disable leading space
          B       %BT01

getwordlength
          MOV     r6, lr
          MOV     r10, r9            ; first copy context
          MOV     r2, stack
          MOV     r7, r1
copycontextpp
          CMP     r9, r2
          LDRNE   r0, [r9, #-4]!
          Push    r0, NE
          BNE     copycontextpp

          MOV     r2, #0             ; word length
02        BL      getbytepp
          CMP     R0, #31
          CMPNE   R0, #" "+1
          ADDGE   r2, r2, #1
          BGE     %BT02
          MOV     r1, r7
          MOV     stack, r9
          MOV     r9, r10
          MOV     pc, r6

getbytepp LDRB    r0, [r1], #1
          CMP     r0, #TokenEscapeChar
          BEQ     gettokenpp
          CMP     r0, #0
Kevin Bracey's avatar
Kevin Bracey committed
345
          MOVNE   pc, lr
Neil Turton's avatar
Neil Turton committed
346
          CMP     stack, r9
Kevin Bracey's avatar
Kevin Bracey committed
347
          MOVHS   pc, lr
Neil Turton's avatar
Neil Turton committed
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
          Pull    r1                ; back to previous token
          B       getbytepp

gettokenpp
          LDRB    r0, [r1], #1      ; tokno
          Push    r1                ; save context
          CMP     r0, #0
          MOVEQ   r1, r12
          BEQ     getbytepp
          MOV     r1, r11
gtoklp    SUBS    r0, r0, #1
          LDRNEB  r8, [r1]
          ADDNE   r1, r1, r8
          BNE     gtoklp
          ADD     r1, r1, #1
          B       getbytepp

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

ReadWindowWidth ROUT    ; read "number of chars printable after Newline
                        ;       before we're on the next line"
        MOV     R0, #VduExt_WindowWidth
ReadVduVarForSam
        Push   "R0, R1, lr"      ; R1 reserves space
        MOV     R0, #-1
        STR     R0, [stack, #4]  ; overwrite R1 value
        MOV     R0, sp
        MOV     R1, sp
        SWI     XOS_ReadVduVariables
Jeffrey Lee's avatar
Jeffrey Lee committed
377 378
        LDR     R0, [sp], #8
        LDR     pc, [sp], #4
Neil Turton's avatar
Neil Turton committed
379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395

;*****************************************************************************
; R0 -> envstring, R1 -> 5 byte time

WriteEnv_SWICode ROUT ; for debugger use
        CMP     R0, #0
        BEQ     %FT01
        LDR     R10, =EnvString
        MOV     R11, R0
02      LDRB    R12, [R11], #1
        CMP     R12, #" "
        MOVLT   R12, #0
        STRB    R12, [R10], #1
        BGE     %BT02

01      CMP     R1, #0
        ExitSWIHandler EQ
Jeffrey Lee's avatar
Jeffrey Lee committed
396
        LDR     R10, =ZeroPage+EnvTime
Neil Turton's avatar
Neil Turton committed
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
        MOV     R11, #4
03      LDRB    R12, [R1, R11]
        STRB    R12, [R10, R11]
        SUBS    R11, R11, #1
        BPL     %BT03
        ExitSWIHandler

;*****************************************************************************

; LET RdArgs() BE
;  R0 ptr to key defn string
;  R1 ptr to command line to decode
;  R2 ptr to workspace
;  R3 size of workspace
; Returns R3 size left

; Flags used in initial args decoding

AFlag       *  1:SHL:8     ; flags shifted up a byte; avoid looking like chars.
KFlag       *  1:SHL:9
SFlag       *  1:SHL:10
EFlag       *  1:SHL:11
GFlag       *  1:SHL:12
420 421 422
UnsetBase   *  &FF000000   ; only if all bits set (cannot be RAM address)

PresentFlag *  &7FFFFFFF
Neil Turton's avatar
Neil Turton committed
423 424 425 426 427 428 429 430 431 432 433
AbsentFlag  *  0

; Type flags

EndType     *   0
FlagType    *   1
KeywordType *   2
ItemType    *   3

RdArgs_SWICode ROUT

Kevin Bracey's avatar
Kevin Bracey committed
434
      WritePSRc SVC_mode, R10
Neil Turton's avatar
Neil Turton committed
435 436 437 438

      Push   "R4, R8, R9, lr"
      MOV     R10, R2             ; R10 points at next available word
      MOV     R12, R0
439
01    MOV     R11, #UnsetBase
Neil Turton's avatar
Neil Turton committed
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492
      SUBS    R3, R3, #4
      BMI     %FT99               ; insufficient space
      STR     R11, [R10], #4
02    LDRB    R11, [R12], #1
      CMP     R11, #"/"
      BNE     %FT03
      LDRB    R11, [R12], #1
      UpperCase R11, R9
      CMP     R11, #"A"
      MOVEQ   R11, #AFlag
      CMP     R11, #"K"
      MOVEQ   R11, #KFlag
      CMP     R11, #"S"
      MOVEQ   R11, #SFlag
      CMP     R11, #"E"
      MOVEQ   R11, #EFlag
      CMP     R11, #"G"
      MOVEQ   R11, #GFlag
      CMP     R11, #256
      LDRGE   R9, [R10, #-4]
      ORRGE   R9, R11, R9
      STRGE   R9, [R10, #-4]
03
      CMP     R11, #","
      BEQ     %BT01
      CMP     R11, #" "
      BGE     %BT02

; Initialisation complete: all flags set, R10 implies number of args.
      MOV     R8, R10

10    BL      RdItem
      BVS     %FT90
      CMP     R12, #KeywordType
      BNE     %FT11
      ADD     R11, R2, R4, LSL #2           ; keyword ptr
      BL      RdItem
      BVS     %FT90
      CMP     R12, #ItemType
      BNE     %FT98
      BL      SetKeyword
      BVS     %FT90
      B       %BT10

11    CMP     R12, #ItemType
      BNE     %FT12

; next positional arg := itemptr

      MOV     R11, R2
20    CMP     R11, R8
      BEQ     %FT98               ; no more positional args
      LDR     R12, [R11], #4
493 494
      CMP     R12, #UnsetBase
      BLO     %BT20
Neil Turton's avatar
Neil Turton committed
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
      TST     R12, #KFlag :OR: SFlag
      BNE     %BT20
      SUB     R11, R11, #4
      BL      SetKeyword
      BVS     %FT90
      B       %BT10

12    CMP     R12, #EndType
      BNE     %BT10

; postscan to check all /a args set.
      MOV     R12, R2
30    CMP     R12, R8
      BEQ     %FT31
      LDR     R11, [R12], #4
510 511
      CMP     R11, #UnsetBase
      BLO     %BT30
Neil Turton's avatar
Neil Turton committed
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554
      TST     R11, #AFlag
      BNE     %FT98          ; bum args error
      MOV     R11, #AbsentFlag
      STR     R11, [R12, #-4]     ; force "not present"
      B       %BT30

31
      Pull   "R4, R8, R9, lr"
      ExitSWIHandler

98    ADR     R0, ErrorBlock_BadParameters
    [ International
      BL      TranslateError
    ]
      B       %FT90

99    ADRL    R0, ErrorBlock_BuffOverflow
    [ International
      BL      TranslateError
    ]
90
      Pull   "R4, R8, R9, lr"
      B      SLVK_SetV

      MakeErrorBlock BadParameters
      MakeErrorBlock ArgRepeated
      ALIGN

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; RdItem: strips next item from command line
; In:  R1 -> cmd line
; Out: R1 updated
;      R12 contains type
;      R4 contains ptr for Item, argno for Flag/Keyword
; VS means buffer full
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

RdItem    ROUT
      Push  "R1, R7, R8, lr"
      MOV    R8, #0              ; not demanding new arg
01    LDRB   R12, [R1], #1
      CMP    R12, #" "
      BEQ    %BT01
Kevin Bracey's avatar
Kevin Bracey committed
555 556 557 558 559
      BGE    %FT33
      MOV    R12, #EndType
      CLRV
      Pull  "R1, R7, R8, PC"
33
Neil Turton's avatar
Neil Turton committed
560 561 562 563 564 565 566 567 568
      CMP    R12, #""""
      BEQ    ohnoitsquotedargumentsagain

      CMP    R12, #"-"      ; options?
      BNE    %FT02          ; nope - boring item
05    BL     GetArg
      LDRVS  R1, [stack]
      BVS    %FT02          ; not recognised - boring item
      STR    R1, [stack]    ; new restore value.
569
      MRS    R12, CPSR
Kevin Bracey's avatar
Kevin Bracey committed
570
      Push   R12            ; save EQ/NE
Neil Turton's avatar
Neil Turton committed
571
      LDR    R12, [R2, R4, LSL #2]
572 573
      CMP    R12, #UnsetBase
      BHS    %FT34
Kevin Bracey's avatar
Kevin Bracey committed
574
      ADR    R0, ErrorBlock_ArgRepeated
Neil Turton's avatar
Neil Turton committed
575
    [ International
Kevin Bracey's avatar
Kevin Bracey committed
576
      BL     TranslateError
Robert Sprowson's avatar
Robert Sprowson committed
577 578
    |
      SETV
Neil Turton's avatar
Neil Turton committed
579
    ]
Kevin Bracey's avatar
Kevin Bracey committed
580 581 582
      ADD    stack, stack, #4 ; discard PSR
      Pull  "R1, R7, R8, PC"
34
Neil Turton's avatar
Neil Turton committed
583
      ANDS   R12, R12, #SFlag
Kevin Bracey's avatar
Kevin Bracey committed
584 585 586 587 588 589
      BNE    %FT35
      MOV    R12, #KeywordType
      ADD    stack, stack, #4 ; discard PSR
      CLRV
      Pull  "R1, R7, R8, PC"
35
Neil Turton's avatar
Neil Turton committed
590 591 592 593 594 595 596 597 598 599 600 601 602 603
      MOV    R12, #PresentFlag
      STR    R12, [R2, R4, LSL #2]

; now deal with flag elision: if nextchar valid keyword char, rescan
      Pull   R12
      TST    R12, #Z_bit
      BEQ    %FT20          ; GetArg returned NE, so not single char abbr
      Push  "R2, R3"
      LDRB   R2, [R1]
      BL     CheckR2OKChar
      Pull  "R2, R3"
      MOVEQ  R8, #1        ; MUST get another arg
      BEQ    %BT05
20    MOV    R12, #FlagType
Kevin Bracey's avatar
Kevin Bracey committed
604 605
      CLRV
      Pull  "R1, R7, R8, PC"
Neil Turton's avatar
Neil Turton committed
606 607

02    CMP    R8, #0
Kevin Bracey's avatar
Kevin Bracey committed
608 609
      BEQ    %FT39
      ADR    R0, ErrorBlock_BadParameters
Neil Turton's avatar
Neil Turton committed
610
    [ International
Kevin Bracey's avatar
Kevin Bracey committed
611
      BL     TranslateError
Robert Sprowson's avatar
Robert Sprowson committed
612
    |
Kevin Bracey's avatar
Kevin Bracey committed
613
      SETV
Robert Sprowson's avatar
Robert Sprowson committed
614
    ]
Kevin Bracey's avatar
Kevin Bracey committed
615 616
      Pull  "R1, R7, R8, PC"
39
Neil Turton's avatar
Neil Turton committed
617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633
   ; copy arg until <" "

      MOV    R7, #" "
      SUB    R1, R1, #1
06    MOV    R4, R10
03    LDRB   R12, [R1], #1
      CMP    R12, R7
      CMPNE  R12, #" "-1
      BLE    %FT04
10
      SUBS   R3, R3, #1
      STRPLB R12, [R10], #1
      BPL    %BT03
23
      ADRL   R0, ErrorBlock_BuffOverflow
    [ International
      BL     TranslateError
Robert Sprowson's avatar
Robert Sprowson committed
634
    |
Kevin Bracey's avatar
Kevin Bracey committed
635
      SETV
Robert Sprowson's avatar
Robert Sprowson committed
636
    ]
Kevin Bracey's avatar
Kevin Bracey committed
637
      Pull  "R1, R7, R8, PC"
Neil Turton's avatar
Neil Turton committed
638 639 640 641 642 643 644 645 646 647 648 649 650 651 652

04    CMP    R7, #""""
      BNE    %FT07
      CMP    R12, #""""
      BNE    %FT08
      LDRB   R12, [R1], #1
      CMP    R12, #""""
      BEQ    %BT10
07    MOV    R12, #0            ; terminate
      SUBS   R3, R3, #1
      BMI    %BT23
      STRB   R12, [R10], #1
      MOV    R12, #ItemType
      SUB    R1, R1, #1
      STR    R1, [stack]
Kevin Bracey's avatar
Kevin Bracey committed
653 654
      CLRV
      Pull  "R1, R7, R8, PC"
Neil Turton's avatar
Neil Turton committed
655 656 657 658 659 660 661 662

ohnoitsquotedargumentsagain
      MOV    R7, #""""
      B      %BT06

08    ADRL   R0, ErrorBlock_BadString
    [ International
      BL     TranslateError
Robert Sprowson's avatar
Robert Sprowson committed
663
    |
Kevin Bracey's avatar
Kevin Bracey committed
664
      SETV
Robert Sprowson's avatar
Robert Sprowson committed
665
    ]
Kevin Bracey's avatar
Kevin Bracey committed
666
      Pull  "R1, R7, R8, PC"
Neil Turton's avatar
Neil Turton committed
667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; GetArg
; Look through keys: allow only full match on first pass, then
;  single char abbreviation on second pass
; Return V set if not key, EQ if single letter abbreviation
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

GetArg    ROUT
; In:  R0 ptr to keystring
;      R1 ptr to potential option.
; Out: VS if nomatch or
;      R1 updated
;      R4 argument number

      Push   "R0-R3, R5-R6, lr"
      MOV     R6, #-1             ; pass number
20    MOV     R4, #0

01    LDRB    R2, [R0], #1
      CMP     R2, #" "
      BEQ     %BT01

02    BL      CheckR2OKChar
      BNE     %FT03             ; matched in full
      LDRB    R3, [R1], #1
      UpperCase R2, R5
      UpperCase R3, R5
      CMP     R2, R3
      LDREQB  R2, [R0], #1
      BEQ     %BT02

      CMP     R6, #0
      BLT     %FT04

; 2nd pass: allow abbreviation
; IF single char abbreviation THEN success ELSE skip
      LDR     R2, [stack, #4]
      SUB     R2, R1, R2          ; length of match+1
      CMP     R2, #2
      SUBEQ   R1, R1, #1
      BEQ     %FT13               ; success

; skip to next keyword
04    LDRB    R2, [R0], #1
      CMP     R2, #" "
      BLT     %FT05
      CMP     R2, #","
      ADDEQ   R4, R4, #1
      CMPNE   R2, #"="
      BNE     %BT04
      LDR     R1, [stack, #4]
      B       %BT01

03  ; NE on first pass: check input string terminated OK
      LDRB    R2, [R1]            ; check for end of input word
      BL      CheckR2OKChar
      BNE     %FT13               ; yaay! full & correct match
      SUB     R0, R0, #1
      B       %BT04

05    ADDS    R6, R6, #1
      LDMLEFD stack, {R0, R1}
      BLE     %BT20
Kevin Bracey's avatar
Kevin Bracey committed
731 732
      SETV
      Pull   "R0-R3, R5-R6, PC"   ; back with failure
Neil Turton's avatar
Neil Turton committed
733 734

13    STR     R1, [stack, #4]
Kevin Bracey's avatar
Kevin Bracey committed
735
      CLRPSR  V_bit, R0           ; clrV (just)
Neil Turton's avatar
Neil Turton committed
736 737 738 739 740
      Pull   "R0-R3, R5-R6, PC"   ; back with success

CheckR2OKChar ROUT
      CMP     R2, #"A"
      RSBGES  R3, R2, #"Z"
Kevin Bracey's avatar
Kevin Bracey committed
741
      BGE     %FT50
Neil Turton's avatar
Neil Turton committed
742 743
      CMP     R2, #"a"
      RSBGES  R3, R2, #"z"
Kevin Bracey's avatar
Kevin Bracey committed
744
      BGE     %FT50
Neil Turton's avatar
Neil Turton committed
745 746
      CMP     R2, #"0"
      RSBGES  R3, R2, #"9"
Kevin Bracey's avatar
Kevin Bracey committed
747
      BGE     %FT50
Neil Turton's avatar
Neil Turton committed
748
      CMP     R2, #"_"
Kevin Bracey's avatar
Kevin Bracey committed
749 750 751
      MOV     PC, lr
50    CMP     R0, R0            ; set EQ
      MOV     PC, lr
Neil Turton's avatar
Neil Turton committed
752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767

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

SetKeyword    ROUT
; R11 ptr at keyword flags
; R4 ptr to value
      Push   "R0-R2, R5, R6, lr"
      LDR     R0, [R11]
      TST     R0, #EFlag :OR: GFlag
      STR     R4, [R11]           ; result will always be here anyway
      BEQ     %FT01
      SUB     R5, R10, R4         ; length of value
      ADD     R3, R3, R5          ; increase free space
      ADD     R2, R5, #11         ; round up to nearest word, then 1
      BIC     R2, R2, #3

Kevin Bracey's avatar
Kevin Bracey committed
768 769
      MOV     R6, stack            ; STR stack, [stack, -R2]! is unpredictable
      STR     R6, [stack, -R2]!    ; reserve stack frame
Neil Turton's avatar
Neil Turton committed
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

      ADD     R2, stack, #4        ; input value ptr
03    LDRB    R6, [R4, R5]
      STRB    R6, [R2, R5]
      SUBS    R5, R5, #1
      BPL     %BT03               ; copy the value

      TST     R0, #EFlag
      MOV     R0, R2
      BNE     %FT02
      ADD     R1, R4, #2          ; free space pointer
      SUBS    R3, R3, #2
      MOV     R2, R3
      BMI     %FT04
      ORR     R2, R2, #1:SHL:31
      SWI     XOS_GSTrans
05    SUB     R3, R3, R2
      ADD     R10, R1, R2        ; update freespace pointer
      STRB    R2, [R1, #-2]
      MOV     R2, R2, LSR #8
      STRB    R2, [R1, #-1]
      BCS     %FT04

90    LDR     stack, [stack, #0]  ; unwind frame (and don't let AAsm use
      STRVS   R0, [stack]         ;   postindexed!!!)
Kevin Bracey's avatar
Kevin Bracey committed
795
      Pull   "R0-R2, R5, R6,PC"
Neil Turton's avatar
Neil Turton committed
796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828

04    ADRL    R0, ErrorBlock_BuffOverflow
    [ International
      BL      TranslateError
    |
      SETV
    ]
      B       %BT90

02    ADD     R1, R4, #3        ; free space pointer
      SUBS    R3, R3, #3        ; adjust for type (1 byte) + length (2 bytes)
      BMI     %BT04
      MOV     R2, R3
      SWI     XOS_EvaluateExpression
      BVS     %BT90
      TEQ     R1, #0, 2         ; if non-zero, then string, so update length
      MOVNE   R14, #1           ; set type byte to definitely non-zero
      STRNEB  R14, [R4]
      BNE     %BT05             ; (C=0 so no buffer overflow, V=0 from SWI)
      STRB    R1, [R4]          ; set type byte to zero (=> integer)
      SUBS    R3, R3, #5
      BMI     %BT04
      STRB    R2, [R4, #1]
      MOV     R2, R2, LSR #8
      STRB    R2, [R4, #2]
      MOV     R2, R2, LSR #8
      STRB    R2, [R4, #3]
      MOV     R2, R2, LSR #8
      STRB    R2, [R4, #4]
      ADD     R10, R4, #5
      B       %BT90

01
Kevin Bracey's avatar
Kevin Bracey committed
829 830
      CLRV
      Pull   "R0-R2, R5, R6,PC"
Neil Turton's avatar
Neil Turton committed
831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853


; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ReadRAMFSLimits
; Return R0 start, R1 end (i.e. 1st byte out of area)

ReadRAMFSLimits_Code ROUT
        Push    "lr"
        MOV     r0, #ChangeDyn_RamFS
        SWI     XOS_ReadDynamicArea     ; out: r0 = base, r1 = current size
        Pull    "lr"
        ADDVC   r1, r1, r0              ; if no error, make r1 -> after end
        ORRVS   lr, lr, #V_bit          ; if error, then set V_bit on return
        ExitSWIHandler

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ExitAndDie
; r0-r2 parameters for Exit
; r3 pointer to module name

TerminateAndSodOff ROUT

        Push    "r0-r2"
Jeffrey Lee's avatar
Jeffrey Lee committed
854
        LDR     r10, =ZeroPage
855
      [ ZeroPage = 0
Neil Turton's avatar
Neil Turton committed
856
        STR     r10, [r10, #Curr_Active_Object]
857 858 859 860
      |
        MOV     r14, #0
        STR     r14, [r10, #Curr_Active_Object]
      ]
Neil Turton's avatar
Neil Turton committed
861 862 863 864 865 866 867 868 869 870 871 872 873 874
        MOV     r1, r3
        MOV     r0, #ModHandReason_Delete
        SWI     XOS_Module
        Pull    "r0-r2"
        SWI     XOS_Exit

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; AddCallBack entry to callback vector
; r0 address to call
; r1 workspace ptr

AddCallBack_Code  ROUT

      Push   "r0-r3, lr"
875 876
  [ ChocolateSysHeap
      ASSERT  ChocolateCBBlocks = ChocolateBlockArrays + 0
Jeffrey Lee's avatar
Jeffrey Lee committed
877
      LDR     r3,=ZeroPage+ChocolateBlockArrays
878 879 880 881 882
      LDR     r3,[r3,#0]
      BL      ClaimChocolateBlock
      MOVVS   r3, #12
      BLVS    ClaimSysHeapNode
  |
Neil Turton's avatar
Neil Turton committed
883 884
      MOV     r3, #12
      BL      ClaimSysHeapNode
885
  ]
Neil Turton's avatar
Neil Turton committed
886 887
      BVS     %FT99
      Pull   "r0, r1"
Jeffrey Lee's avatar
Jeffrey Lee committed
888
      LDR     r10, =ZeroPage
Kevin Bracey's avatar
Kevin Bracey committed
889
      WritePSRc SVC_mode+I_bit, r3      ; IRQs off while holding context.
Neil Turton's avatar
Neil Turton committed
890
      LDR     r3, [r10, #CallBack_Vector]
891
 [ {TRUE}
Neil Turton's avatar
Neil Turton committed
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
      STR     r3, [r2, #0]
      STMIB   r2, {r0, r1}
      STR     r2, [r10, #CallBack_Vector]
      Pull   "r2, r3, lr"
 |
      STR     r3, [r2], #4
      STMIA   r2, {r0, r1}
      SUB     r2, r2, #4
      STR     r2, [r10, #CallBack_Vector]
      Pull   "r2, r3, lr"
      MOV     r10, #0
 ]
      LDRB    r11, [r10, #CallBack_Flag]
      ORR     r11, r11, #CBack_VectorReq
      STRB    r11, [r10, #CallBack_Flag]
      B       SLVK

99      STR     r0, [stack]
        Pull    "r0-r3, lr"
        B       SLVK_SetV

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;       RemoveCallBack - Entry for SWI OS_RemoveCallBack
;
;       Removes an entry on the callback vector before it has been called
;
; in:   r0 = address that would have been called
;       r1 = workspace ptr
;
; out:  -
;

RemoveCallBack ROUT
        Push    "r2-r4"
Kevin Bracey's avatar
Kevin Bracey committed
927
        SavePSR r10                     ; save old I bit
Neil Turton's avatar
Neil Turton committed
928
10
Kevin Bracey's avatar
Kevin Bracey committed
929
        WritePSRc SVC_mode+I_bit, r11   ; disable IRQs while looking at list
Jeffrey Lee's avatar
Jeffrey Lee committed
930
        LDR     r11, =ZeroPage
Neil Turton's avatar
Neil Turton committed
931 932 933 934 935 936 937 938 939 940 941 942 943 944
        LDR     r2, [r11, #CallBack_Vector]! ; r11 -> prev, r2 -> this
20
        TEQ     r2, #0
        Pull    "r2-r4", EQ
        ExitSWIHandler EQ

        LDMIA   r2, {r3,r4,r12}         ; r3 -> next, r4 = addr, r12 = ws
        TEQ     r4, r0                  ; check if correct address
        TEQEQ   r12, r1                 ; and correct ws ptr
        MOVNE   r11, r2                 ; if not, then prev:=this
        MOVNE   r2, r3                  ; and this:=next
        BNE     %BT20                   ; and loop

        STR     r3, [r11]               ; prev.link := next
Kevin Bracey's avatar
Kevin Bracey committed
945
        RestPSR r10                     ; safe now to restore IRQ status
Neil Turton's avatar
Neil Turton committed
946 947

        Push    "r0, r1, lr"            ; now free this node
948 949
  [ ChocolateSysHeap
        ASSERT  ChocolateCBBlocks = ChocolateBlockArrays + 0
Jeffrey Lee's avatar
Jeffrey Lee committed
950
        LDR     r1,=ZeroPage+ChocolateBlockArrays
951 952 953 954
        LDR     r1,[r1,#0]
        BL      FreeChocolateBlock
        BLVS    FreeSysHeapNode
  |
Neil Turton's avatar
Neil Turton committed
955 956 957
        BL      FreeSysHeapNode         ; and then start again (NB we must
                                        ; restart from head of list again, as
                                        ; enabling IRQs could have changed list
958
  ]
Neil Turton's avatar
Neil Turton committed
959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977
        STRVS   r0, [sp, #0]
        Pull    "r0, r1, lr"
        BVC     %BT10

        Pull    "r2-r4"                 ; had an error while releasing block
        ORR     lr, lr, #V_bit
        ExitSWIHandler

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; SWI OS_Confirm

; If pointer visible, change pointer shape and look at mouse keys too.
;                     Flush mouse buffer first.
; Wait until key pressed.
; Returns: (lowercased) character in r0 (if mouse scanned, LH button = 'y',
;                                        other buttons = 'n')
; C set for Escape condition
; EQ set if r0 = 'y'

Kevin Bracey's avatar
Kevin Bracey committed
978
 [ International
Neil Turton's avatar
Neil Turton committed
979
confirm_yn      DCB "YesNo:yn",0        ; Token to lookup message for Yes/No
Kevin Bracey's avatar
Kevin Bracey committed
980 981 982
 |
confirm_yn      DCB "yn"
 ]
Neil Turton's avatar
Neil Turton committed
983 984 985
ptr_confirm     DCB "ptr_confirm",0     ; Wimp's confirm pointer sprite shape
confirm_scale   DCD 1,1,1,1             ; Scaling factor for sprite op
Confirm_Code ROUT
Kevin Bracey's avatar
Kevin Bracey committed
986
        WritePSRc SVC_mode, r10         ; enable IRQs
Neil Turton's avatar
Neil Turton committed
987 988 989 990 991
        Push   "r0-r7, lr"

; Lookup the symbols for Y/N

        ADR     r0, confirm_yn
Kevin Bracey's avatar
Kevin Bracey committed
992
 [ International
Neil Turton's avatar
Neil Turton committed
993
        BL      FindToken               ; Lookup in messages, use default if error
Kevin Bracey's avatar
Kevin Bracey committed
994
 ]
Neil Turton's avatar
Neil Turton committed
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 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048
        LDRB    r1, [r0], #1            ; Y character
        LDRB    r2, [r0], #1            ; N character
        ORR     r1, r1, r2, LSL #8
        Push    "r1"                    ; Y=[sp], N=[sp+1]

; Save current pointer selected

        MOV     r0, #106
        MOV     r1, #255                ; read pointer state
        SWI     XOS_Byte
        BVS     confirm_error
        BIC     r2, r1, #&80
        MOV     r10, r1
        TST     r10, #15                ; Pointer enabled?
        BEQ     confirm_waitloop        ; Jump if not

; Find Wimp's "ptr_confirm" sprite, searching first RMA then ROM

        SWI     XWimp_BaseOfSprites
        MOVVS   r10, #0                 ; If error then don't use mouse
        BVS     confirm_waitloop        ; And jump to poll keyboard

        MOV     r11, r0                 ; Save -> ROM sprites, r1 -> RMA sprites
        ADR     r2, ptr_confirm         ; -> sprite name
        MOV     r0, #&128               ; Read sprite info
        SWI     XOS_SpriteOp
        BVC     %FT10                   ; Jump if sprite in RMA

        ADR     r2, ptr_confirm         ; -> sprite name
        MOV     r1, r11                 ; -> ROM sprites
        MOV     r0, #&128               ; Read sprite info
        SWI     XOS_SpriteOp
        MOVVS   r10, #0                 ; If error then don't use mouse
        BVS     confirm_waitloop        ; And jump to poll keyboard

; Set pointer shape from the sprite area found (r1)

10      MOV     r7, #0                  ; No pixel translation
        ADR     r6, confirm_scale       ; pointer scaling factor (1:1)
        MOV     r5, #0                  ; y hot spot offset
        MOV     r4, #0                  ; x hot spot offset
        MOV     r3, #&23                ; No palette, shape 3
        ADR     r2, ptr_confirm         ; -> sprite name
        MOV     r0, #&124               ; Set pointer shape
        SWI     XOS_SpriteOp            ; Ignore errors

        MOV     r0, #21
        MOV     r1, #9
        SWI     XOS_Byte                ; flush mouse buffer

        MOV     r0, #&C4
        MOV     r1, #0
        MOV     r2, #255
        SWI     XOS_Byte                ; read current repeat rate.
Jeffrey Lee's avatar
Jeffrey Lee committed
1049
        LDR     r0, =ZeroPage
Neil Turton's avatar
Neil Turton committed
1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121
        LDR     r0, [r0, #MetroGnome]
        ADD     r11, r1, r0             ; time to wait for

confirm_mouserepeat
        SWI     XOS_Mouse
        CMP     r2, #0                  ; any buttons down?
        BEQ     confirm_waitloop

        CMP     r3, r11
        BMI     confirm_mouserepeat

confirm_waitloop
        MOV     r0, #129
        MOV     r1, #1
        MOV     r2, #0
        SWI     XOS_Byte                ; scan for key
        BVS     confirm_error
        CMP     r2, #255
        BNE     confirm_gotkey

        TST     r10, #15
        BEQ     confirm_waitloop        ; no mouse scan wanted.

        SWI     XOS_Mouse
        BVS     confirm_error
        CMP     r2, #0
        BEQ     confirm_waitloop

        TST     r2, #4                  ; LH button?
        LDRNEB  r1, [sp]                ; Yes
        LDREQB  r1, [sp, #1]            ; No

confirm_gotkey
        CMP     r2, #&1B                ; ESCAPE or normal char read ?
        ORREQ   r11, r1, #&100
        MOVNE   r11, r1
        LowerCase r11, r1

        TSTS    r10, #15                ; Was pointer changed?
        MOV     r1, r10
        MOV     r0, #106
        SWINE   XOS_Byte                ; Yes then restore shape

        Pull   "r10"                    ; r10=YN
        AND     r10, r10, #&ff          ; Retain Y byte
        Pull   "r0-r7, lr"
        BIC     lr, lr, #C_bit :OR: Z_bit ; SKS. Punter lr has VClear
        AND     r0, r11, #&FF
        TST     r11, #&100              ; ESCAPE condition ? (SKS)
        ORRNE   lr, lr, #C_bit
        CMP     r0, r10
        ORREQ   lr, lr, #Z_bit
        B       SLVK

confirm_error
        ADD     sp, sp, #4              ; Drop YN
        STR     r0, [stack]
        Pull    "r0-r7, lr"
        B       SLVK_SetV


; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; In    r0 = continuation crc (0 to start)
;       r1 -> start of core
;       r2 -> end of core
;       r3 = increment (typically 1, 2 or 4), but can be -ve

; Out   r0 = crc so far

CRC_Code ROUT

        [ {TRUE}
Kevin Bracey's avatar
Kevin Bracey committed
1122
        WritePSRc SVC_mode, r10         ; Could take a long time
Neil Turton's avatar
Neil Turton committed
1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163

        Push    "r3, r14"
        TEQ     r3, #0                  ; is increment 0? - if so, it's silly
        BEQ     %FT80                   ; so return error, rather than going on forever

        MOV     r10, r1
        MOV     r12, #&A000             ; CRC EOR pattern = &A001
        ORR     r12, r12, #&0001
10
        CMP     r10, r2                 ; Finished ?
        BEQ     %FA90                   ; Must be exact end, allows -ve offset

        LDRB    r14, [r10], r3
        EOR     r0, r0, r14             ; EOR the data with current crc lo
        CMP     r10, r2                 ; length might be odd so check again
        MOVEQ   r11, #8                 ; if equal then only do 8 bits
        BEQ     %FT20

        LDRB    r14, [r10], r3
        EOR     r0, r0, r14, LSL #8     ; EOR the data with current crc hi
        MOV     r11, #16                ; do 16 bits

20
        MOVS    r0, r0, LSR #1          ; acc >>= 1; CS/CC
        EORCS   r0, r0, r12             ; CS -> eor, CC -> ok
        SUBS    r11, r11, #1            ; 8 bits per byte
        BNE     %BT20
        B       %BT10

80
        ADRL    r0, ErrorBlock_BadParameters    ; return "Bad parameters" error
 [ International
        BL      TranslateError
 ]
        Pull    "r3, r14"
        B       SLVK_SetV

90
        Pull    "r3, r14"
        ExitSWIHandler
        |
Kevin Bracey's avatar
Kevin Bracey committed
1164
        WritePSRc SVC_mode, r10         ; Could take a long time
Neil Turton's avatar
Neil Turton committed
1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200

        Push    "r3, r4, lr"
        MOV     r10, r1
        MOV     r12, #&A000             ; CRC EOR pattern = &A001
        ORR     r12, r12, #&0001
        MOV     r14, #1                 ; A single bit to be shifted

10      CMP     r10, r2                 ; Finished ?
        BEQ     %FA90                   ; Must be exact end, allows -ve offset

        LDRB    r4, [r10], r3
        MOV     r11, #0                 ; Go round the bits

20      TST     r4, r14, LSL r11        ; Is data bit = carry ?; NE/EQ
        BEQ     %FT30

        MOVS    r0, r0, LSR #1          ; acc >>= 1; CS/CC
        EORCC   r0, r0, r12             ; NE, CC -> eor, NE, CS -> ok
        B       %FT40

30      MOVS    r0, r0, LSR #1          ; acc >>= 1; CS/CC
        EORCS   r0, r0, r12             ; EQ, CS -> eor, EQ, CC -> ok

40      ADD     r11, r11, #1            ; 8 bits per byte
        CMP     r11, #8
        BLO     %BT20

        B       %BT10

90      Pull    "r3, r4, lr"
        ExitSWIHandler
        ]

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

        END