ArthurSWIs 38.7 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 21 22 23 24 25 26 27 28 29 30
; 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     => ArthurSWIs - ReadUnsigned, Vectors, Bits

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; ReadUnsigned.
; ============
;
; Read an unsigned number from a string in decimal (no prefix), hex (&)
; or given base (nn_). Leading spaces are stripped.
; 'Bad base for number' is given if a base is not in 02..10_36
; 'Bad number' is given if
;      (i) No valid number was
;  or (ii) a '<base>_' or '&' has no following valid number
; 'Number too big' is given if the result overflowed a 32-bit word

; In    r1 -> string
Ben Avison's avatar
Ben Avison committed
31
;       r0 =     bits 0-7: base to read number in (0 means any based number allowed)
Neil Turton's avatar
Neil Turton committed
32 33 34 35
;                bit 31 set -> check term chars for ok-ness
;                bit 30 set -> restrict range to 00..FF
;                bit 29 set -> restrict range to 0..R2 (inclusive)
;                               (overrides bit 30)
Ben Avison's avatar
Ben Avison committed
36 37 38
;                bit 28 set -> read 64-bit value to R2,R3 and
;                               if applicable, range is in R2,R3
;       r4 != &45444957 ("WIDE") -> legacy mode: bits 8-28 are considered part of the base
Neil Turton's avatar
Neil Turton committed
39 40 41

; Out   VC : r1 -> first unused char, r2 = number
;       VS : r1 unchanged, r2 = 0, current error block set
Ben Avison's avatar
Ben Avison committed
42
;       either way, R4 = mask of flag bits supported
Neil Turton's avatar
Neil Turton committed
43

Ben Avison's avatar
Ben Avison committed
44
ReadUnsigned_Routine Entry "r0-r1, r3-r6, r9"
Neil Turton's avatar
Neil Turton committed
45

Kevin Bracey's avatar
Kevin Bracey committed
46
        WritePSRc SVC_mode, r9
Neil Turton's avatar
Neil Turton committed
47

Ben Avison's avatar
Ben Avison committed
48 49 50 51 52 53 54 55 56 57
        LDR     lr, =&45444957
        CMP     r4, lr
        MOVEQ   r4, #(2_1111 :SHL: 28)
        MOVNE   r4, #(2_111 :SHL: 29)
        STREQ   r4, [stack, #3*4]

        AND     r11, r0, r4       ; Remember the input flags
        ANDEQ   r12, r0, #255     ; r12 := base
        BICNE   r12, r0, r4

Neil Turton's avatar
Neil Turton committed
58
; first set range limit
Ben Avison's avatar
Ben Avison committed
59 60 61 62 63
        MOV     r9, r2            ; limit value lo word
        TST     r11, #1 :SHL: 28
        MOVEQ   r6, #0            ; limit value hi word
        MOVNE   r6, r3
        TST     r11, #3 :SHL: 29
Neil Turton's avatar
Neil Turton committed
64
        MOVEQ   r9, #-1           ; used unsigned; allows anything
Ben Avison's avatar
Ben Avison committed
65 66
        MOVEQ   r6, #-1
        TST     r11, #1 :SHL: 30
Neil Turton's avatar
Neil Turton committed
67
        MOVNE   r9, #&FF
Ben Avison's avatar
Ben Avison committed
68
        MOVNE   r6, #0
Neil Turton's avatar
Neil Turton committed
69 70 71 72 73 74 75 76 77 78 79 80 81

        CMP     r12, #2          ; If base nonsensical, default to 10
        RSBGES  r14, r12, #36    ; ie. try to match most generally
        MOVLT   r12, #10

01      LDRB    r0, [r1], #1    ; Skip spaces for Bruce
        TEQ     r0, #" "
        BEQ     %BT01
        SUB     r10, r1, #1      ; Keep ptr to start of string after spaces

        TEQ     r0, #"&"        ; '&' always forces hex read
        BNE     %FT20
        MOV     r4, #16
Ben Avison's avatar
Ben Avison committed
82 83 84 85 86
        TST     r11, #1 :SHL: 28
        ADR     lr, %FT09
        BEQ     ReadNumberInBase
        BNE     Read64BitNumberInBase
09      BVS     %FT95
Neil Turton's avatar
Neil Turton committed
87 88 89 90 91 92 93 94

10      STR     r1, [sp, #4]       ; Update string^
        TST     r11, #(1 :SHL: 31) ; Was the termcheck flag set ?
        BEQ     %FT15
        LDRB    r0, [r1]           ; What was the term char ?
        CMP     r0, #" "           ; CtrlChar + space all ok
        BGT     %FT85              ; For bad term errors

Ben Avison's avatar
Ben Avison committed
95 96 97 98 99
15      CMP     r9, r2
        SBCS    lr, r6, r5
        BCC     %FT80
        TST     r11, #1 :SHL: 28
        STRNE   r5, [stack, #4*2]
Neil Turton's avatar
Neil Turton committed
100 101 102 103 104 105 106 107 108
        PullEnv
        ExitSWIHandler          ; VClear already in lr


20      SUB     r1, r1, #1      ; Skip back to first char of string
        MOV     r4, #10         ; Try reading a decimal number
        BL      ReadNumberInBase
        MOVVS   r4, r12          ; If we failed to read a decimal number
        BVS     %FT30           ; then use the one supplied (r12). r1 ok
Ben Avison's avatar
Ben Avison committed
109
        LDRB    r0, [r1], #1    ; Is it base_number ?
Neil Turton's avatar
Neil Turton committed
110 111 112 113 114 115 116 117 118 119
        CMP     r0, #"_"        ; If not based, use supplied base
        MOVNE   r1, r10         ; to read from given start of string (spaces !)
        MOVNE   r4, r12         ; restore supplied base!
        MOVEQ   r4, r2          ; Use this as new base

; Reading number in base r4

30      CMP     r4, #2          ; Is base valid (2..36) ?
        RSBGES  r0, r4, #36     ; LT -> invalid
        BLT     %FT90
Ben Avison's avatar
Ben Avison committed
120 121 122 123 124
        TST     r11, #1 :SHL: 28
        ADR     lr, %FT39
        BEQ     ReadNumberInBase ; Read rest of number
        BNE     Read64BitNumberInBase
39      BVS     %FT95
Neil Turton's avatar
Neil Turton committed
125 126 127 128 129 130 131 132 133 134 135
        B       %BT10


80      ADR     r2, ErrorBlock_NumbTooBig
        B       %FT95

85      ADR     r2, ErrorBlock_BadNumb
        B       %FT95

90      ADR     r2, ErrorBlock_BadBase

Robert Sprowson's avatar
Robert Sprowson committed
136
95
Neil Turton's avatar
Neil Turton committed
137 138 139 140 141 142 143 144 145
      [ International
        Push    "r0,lr"
        MOV     r0,r2
        BL      TranslateError
        MOV     r2,r0
        Pull    "r0,lr"
      ]
        STR     r2, [stack]     ; Go set the current error
        MOV     r2, #0          ; Defined to return 0 on error
Ben Avison's avatar
Ben Avison committed
146 147 148
        TST     r11, #1 :SHL: 28
        STRNE   r2, [stack, #4*2] ; return MSB=0 on error too, if 64-bit read reqd
        PullEnv
Neil Turton's avatar
Neil Turton committed
149 150 151 152 153 154 155 156 157 158 159
        B       SLVK_SetV

        MakeErrorBlock BadBase

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; ReadNumberInBase
; ================

; In    r1 -> string, r4 = base (valid)

Ben Avison's avatar
Ben Avison committed
160
; Out   VC : Number read in r2, r1 updated. r3 = number of chars used, r5 = 0
Neil Turton's avatar
Neil Turton committed
161 162
;       VS : r1 preserved, r2 -> error block

163
ReadNumberInBase Entry "r0, r1, r12"
Neil Turton's avatar
Neil Turton committed
164 165 166

        MOV     r2, #0          ; Result
        MOV     r3, #0          ; Number of valid digits read
Ben Avison's avatar
Ben Avison committed
167
        MOV     r5, #0
Neil Turton's avatar
Neil Turton committed
168 169 170 171

10      BL      GetCharForReadNumber
        BNE     %FT50           ; Finished ?

Ben Avison's avatar
Ben Avison committed
172 173 174 175 176
        TST     r2, #&F8000000  ; If EQ, can't possibly overflow in any base up to 26
        MLAEQ   r2, r4, r2, r0
        BEQ     %BT10

        MOV     r12, r4
Neil Turton's avatar
Neil Turton committed
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
        MOV     r14, #0         ; Multiply by repeated addition. Base <> 0 !
20      ADDS    r14, r14, r2
        BCS     %FT90           ; Now checks for overflow !
        SUBS    r12, r12, #1    ; result *:= base
        BNE     %BT20
        ADDS    r2, r14, r0     ; result +:= digit
        BCC     %BT10
        B       %FT90           ; Now checks for overflow here too!

50      CMP     r3, #0          ; Read any chars at all ? VClear
        STRNE   r1, [sp, #4]    ; Update string^
        EXIT    NE              ; Resultis r2

      [ International
        Push    "r0"
        ADR     r0, ErrorBlock_BadNumb
        BL      TranslateError
        MOV     r2,r0
        Pull    "r0"
      |
        ADR     r2, ErrorBlock_BadNumb
        SETV
      ]
        EXIT
        MakeErrorBlock BadNumb

90
      [ International
        Push    "r0"
        ADR     r0, ErrorBlock_NumbTooBig
        BL      TranslateError
        MOV     r2,r0
        Pull    "r0"
      |
        ADR     r2, ErrorBlock_NumbTooBig
        SETV
      ]
        EXIT
        MakeErrorBlock NumbTooBig

Ben Avison's avatar
Ben Avison committed
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; Read64BitNumberInBase
; =====================

; In    r1 -> string, r4 = base (valid)

; Out   VC : Number read in r2 (lo) and r5 (hi), r1 updated. r3 = number of chars used
;       VS : r1 preserved, r2 -> error block, r5 corrupted

Read64BitNumberInBase ALTENTRY

        MOV     r2, #0          ; Result lo
        MOV     r3, #0          ; Number of valid digits read
        MOV     r5, #0          ; Result hi

10      BL      GetCharForReadNumber
        BNE     %BT50           ; Finished ?

236
      [ :LNOT: NoARMM
Ben Avison's avatar
Ben Avison committed
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
        TST     r5, #&F8000000  ; If EQ, can't possibly overflow in any base up to 26
        MULEQ   r5, r4, r5      ; r0,r5 = new_digit + (old_msw * base)<<32
        UMLALEQ r0, r5, r4, r2  ; r0,r5 += old_lsw * base
        MOVEQ   r2, r0
        BEQ     %BT10
      ]
                                ; Multiply by repeated addition. Base <> 0 !
        SUBS    r12, r4, #1     ; Final iteration has r2,r5 as dest, so one fewer main iterations
        MOV     r14, #0         ; r0,r14 is accumulator, initialised to new_digit,0
20      ADDS    r0, r0, r2
        ADCS    r14, r14, r5
        BCS     %BT90
        SUBS    r12, r12, #1
        BNE     %BT20
        ADDS    r2, r0, r2
        ADCS    r5, r14, r5
        BCC     %BT10
        B       %BT90           ; Checks for overflow here too!

Neil Turton's avatar
Neil Turton committed
256 257 258 259 260 261 262 263 264 265 266 267
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; GetCharForReadNumber
; ====================
;
; Read a digit and validate for reading in current base. Bases 2..36 are valid

; In    r1 -> string, r4 = base for number input

; Out   EQ -> r0 = valid number in [0..base-1], r1++
;       NE -> r0 invalid, r1 same

268
GetCharForReadNumber Entry
Neil Turton's avatar
Neil Turton committed
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

        LDRB    r0, [r1]
        CMP     r0, #"0"
        BLO     %FT95
        CMP     r0, #"9"
        BLS     %FT50
        UpperCase r0, r14
        CMP     r0, #"A"        ; Always hex it, even if reading in decimal
        RSBGES  r14, r0, #"Z"   ; Inverse compare as nicked from UpperCase
        BLT     %FT95           ; GE -> in range A..Z
        SUB     r0, r0, #"A"-("0"+10)
50      SUB     r0, r0, #"0"
        CMP     r0, r4          ; digit in [0..base-1] ?
        BHS     %FT95
        ADD     r1, r1, #1      ; r1++
        ADD     r3, r3, #1      ; Valid digit has been read
        CMP     r0, r0          ; EQ
        EXIT

95      CMP     r0, #-1         ; NE
        EXIT

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Initialise_vectors()
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

            ^ 0
TailPtr     # 4     ; order very carefully chosen!
VecWSpace   # 4
Address     # 4
VecNodeSize # 0

InitVectors

; for vec:=0 to NVECTORS-1 do vectab!(vec*4):= defaultvectab+8*vec

      MOV   R0, #NVECTORS
      ADR   R1, defaultvectab    ; Point at the default vector table
Jeffrey Lee's avatar
Jeffrey Lee committed
307
      LDR   R2, =ZeroPage+VecPtrTab ; Point at table of head pointers
Neil Turton's avatar
Neil Turton committed
308 309 310 311 312 313 314 315 316 317 318 319 320 321

VecInitLoop
      STR    R1, [R2], #4
      ADD    R1, R1, #VecNodeSize ; defaultvectab+vns*vec
      SUBS   R0, R0, #1             ; Next vec
      BGT    VecInitLoop

      MOV    PC, link
      LTORG

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Call_vector (n)
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; In:   r10 = vector number
Kevin Bracey's avatar
Kevin Bracey committed
322 323
;       lr contains return address
;       cpsr contains flags/int state to set up before calling
Neil Turton's avatar
Neil Turton committed
324 325 326 327 328

; Out:  r10, r12, lr corrupted

CallVector ROUT

329
        MRS     r12, CPSR
Kevin Bracey's avatar
Kevin Bracey committed
330 331 332
        CMP     r10, #NVECTORS
        BHS     CallVecTooHigh          ; return - silly value

333
        MSR     CPSR_f, r12             ; put back caller's flags + int state
Kevin Bracey's avatar
Kevin Bracey committed
334
        Push    lr                      ; claimed return goes back to caller
Neil Turton's avatar
Neil Turton committed
335

Jeffrey Lee's avatar
Jeffrey Lee committed
336
        LDR     r14, =ZeroPage+VecPtrTab ; Point at table of head pointers
Neil Turton's avatar
Neil Turton committed
337 338 339 340 341 342 343 344 345 346 347 348 349
        LDR     r10, [r14, r10, LSL #2] ; nextblock:=vecptrtab!(n*4)

CallVecLoop
        MOV     lr, pc                  ; Set up the return address
        LDMIA   r10, {r10, r12, pc}     ; CALL the vectored routine, step chain

; NB. It is the responsibility of vector code NOT to corrupt flags that are
; part of the input conditions if they are going to pass the call on, eg. INSV
; must not do CMP as C,V are needed by old handler

        TEQ     r10, #0                 ; until nextblock points to zero
        BNE     CallVecLoop

Kevin Bracey's avatar
Kevin Bracey committed
350 351 352
        Pull    pc                      ; can't restore all flags. CV will be preserved

CallVecTooHigh
353
        MSR     CPSR_f, r12
Kevin Bracey's avatar
Kevin Bracey committed
354
        MOV     pc, lr
Neil Turton's avatar
Neil Turton committed
355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;Add_To_vector(n, Addressess)
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Add_ToVector_SWICode   ROUT

      CMP   R0, #NVECTORS
      BCS   BadClaimNumber
      Push "R0-R4, link"
      B     GoForAddToVec

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;Claim_vector(n, Addressess)
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

ClaimVector_SWICode   ROUT
 ; On Entry : R0 = Vector number, R1 = Address, R2 = workspace reqd

      CMP   R0, #NVECTORS
      BCS   BadClaimNumber

      Push "R0-R4, link"

Kevin Bracey's avatar
Kevin Bracey committed
379
        PHPSEI  R4, R14                 ; Disable IRQs
Neil Turton's avatar
Neil Turton committed
380 381

        MOV     R3, #0                  ; List of de-linked nodes is empty
Jeffrey Lee's avatar
Jeffrey Lee committed
382
        LDR     R11, =ZeroPage+VecPtrTab ; Get ptr to table of head pointers
Neil Turton's avatar
Neil Turton committed
383 384 385 386 387 388
        LDR     R10, [R11, R0, LSL #2]! ; R10 "nextblock" := *oldptr, R11= root ptr
01      BL      FindAndDelinkNode       ; R10,R11->R10,R11,R12
        STRVC   R3, [R12, #TailPtr]     ; Attach de-linked nodes onto this node
        MOVVC   R3, R12                 ; New head of de-linked nodes
        BVC     %BT01                   ; Repeat until all nodes de-linked

Kevin Bracey's avatar
Kevin Bracey committed
389
        PLP     R4                      ; Restore IRQ state
Neil Turton's avatar
Neil Turton committed
390 391 392 393 394 395 396

; Free the list of de-linked nodes, pointed to by R3, enter with VS

02      LDRVC   R3, [R3, #TailPtr]      ; Update head of de-linked nodes
        BLVC    FreeNode                ; Free the node pointed to by R12
        SUBS    R12, R3, #0             ; Any more nodes to free?
        BNE     %BT02                   ; Yes then jump
Kevin Bracey's avatar
Kevin Bracey committed
397

Neil Turton's avatar
Neil Turton committed
398
GoForAddToVec
Jeffrey Lee's avatar
Jeffrey Lee committed
399
      LDR   R11, =ZeroPage+VecPtrTab ; Point at table of head pointers
Neil Turton's avatar
Neil Turton committed
400 401 402 403 404

      ADD   R11, R11, R0, LSL #2
      MOV   R10, R1                 ; Address
      MOV   R4, R2                  ; TailPtr pointer is "nextblock"

405 406
  [ ChocolateSysHeap
      ASSERT  ChocolateSVBlocks = ChocolateBlockArrays + 4
Jeffrey Lee's avatar
Jeffrey Lee committed
407
      LDR   r3,=ZeroPage+ChocolateBlockArrays
408 409 410 411 412
      LDR   r3,[r3,#4]
      BL    ClaimChocolateBlock
      MOVVS R3, #VecNodeSize        ; Ask for this number of bytes
      BLVS  ClaimSysHeapNode        ; The result is in R2 : R12 corrupted
  |
Neil Turton's avatar
Neil Turton committed
413 414
      MOV   R3, #VecNodeSize        ; Ask for this number of bytes
      BL    ClaimSysHeapNode        ; The result is in R2 : R12 corrupted
415
  ]
Neil Turton's avatar
Neil Turton committed
416 417
      BVS   BadClaimVector          ; Failed : Exit

Kevin Bracey's avatar
Kevin Bracey committed
418
      WritePSRc SVC_mode+I_bit, R3  ; force noirq
Neil Turton's avatar
Neil Turton committed
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450
      LDR   R3, [R11]               ; "nextblock" :=vecptrtab!(n*4)
      STMIA R2, {R3, R4, R10}       ; Atomic Operation thus links in the new
                                    ; routine
      STR   R2, [R11]               ; vectab!(n*4) := "thisblock"
BadClaimVector
      STRVS R0, [stack]
      Pull "R0-R4, link"
      B    SLVK_TestV

BadClaimNumber
      ADR    R0, ErrorBlock_BadClaimNum
    [ International
      Push   "lr"
      BL     TranslateError
      Pull   "lr"
    ]
      B      SLVK_SetV

      MakeErrorBlock BadClaimNum

;Release_vector(n, Addressess)
;+++++++++++++++++++++++++

ReleaseVector_SWICode
 ; On Entry : R0 = vector number, R1 = Address, R2 = workspace, SVC mode

      CMP   R0, #NVECTORS
      SETV  CS
      BVS   BadVectorRelease

        Push    "R0-R2,R9,link"

Kevin Bracey's avatar
Kevin Bracey committed
451
        PHPSEI  R9, R14                 ; Disable IRQs
Neil Turton's avatar
Neil Turton committed
452

Jeffrey Lee's avatar
Jeffrey Lee committed
453
        LDR     R11, =ZeroPage+VecPtrTab ; Get ptr to table of head pointers
Neil Turton's avatar
Neil Turton committed
454 455
        LDR     R10, [R11, R0, LSL #2]! ; R10 "nextblock" := *oldptr, R11= root ptr
        BL      FindAndDelinkNode       ; R10,R11->R10,R11,R12
Kevin Bracey's avatar
Kevin Bracey committed
456
        PLP     R9                      ; Restore IRQ state
Neil Turton's avatar
Neil Turton committed
457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490
        BLVC    FreeNode                ; If found, free the node in R12

        Pull    "R0-R2,R9,link"

BadVectorRelease
      ADRVS R0, ErrorBlock_NaffRelease
    [ International
      Push  "lr",VS
      BLVS  TranslateError
      Pull  "lr",VS
    ]
      B     SLVK_TestV

      MakeErrorBlock NaffRelease

; Find a node and de-link it from the vector chain
; In:
; R1 = code address
; R2 = workspace address
; R10 -> Node
; R11 -> Root ptr
; Out:
; VC:
; R10 -> Node following found
; R11 -> New root ptr
; R12 -> Node de-linked
; VS:
; R10,11,12 trashed - node not found

10      ADD     R11, R10, #TailPtr      ; oldptr := thisblock+TailPtr
        LDR     R10, [R11]              ; nextblock:=thisblock!TailPtr

FindAndDelinkNode
        CMP     R10, #0                 ; End of chain?
Kevin Bracey's avatar
Kevin Bracey committed
491
        RETURNVS EQ                     ; Yes, return error
Neil Turton's avatar
Neil Turton committed
492 493 494 495 496 497 498 499 500 501 502 503

        LDR     R12, [R10, #VecWSpace]
        CMP     R12, R2                 ; Workspace matches?
        LDREQ   R12, [R10, #Address]
        CMPEQ   R12, R1                 ; And code address matches?
        BNE     %BT10                   ; No then jump, try next node

; Remove node from vector chain

        MOV     R12, R10                ; R12-> node to de-link
        LDR     R10, [R12, #TailPtr]    ; Get link to next node
        STR     R10, [R11]              ; Previous node's link -> next node
Kevin Bracey's avatar
Kevin Bracey committed
504
        RETURNVC EQ                     ; Return no error
Neil Turton's avatar
Neil Turton committed
505 506 507 508 509 510 511 512

; Return node to heap space
; In:
; R12-> node to release

FreeNode
        Push    "R0-R2, lr"
        MOV     R2, R12
513 514
  [ ChocolateSysHeap
        ASSERT  ChocolateSVBlocks = ChocolateBlockArrays + 4
Jeffrey Lee's avatar
Jeffrey Lee committed
515
        LDR     r1,=ZeroPage+ChocolateBlockArrays
516 517 518 519
        LDR     r1,[r1,#4]
        BL      FreeChocolateBlock
        BLVS    FreeSysHeapNode
  |
Neil Turton's avatar
Neil Turton committed
520
        BL      FreeSysHeapNode
521
  ]
Neil Turton's avatar
Neil Turton committed
522 523 524 525 526 527 528 529 530 531 532
        STRVS   R0, [stack]
        Pull    "R0-R2, PC"                     ; returns Vset if sysheap poo'd.

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

      LTORG

defaultvectab
   & 0, 0, NaffVector           ; UserV  * &00
   & 0, 0, ErrHandler           ; ErrorV * &01
   & 0, 0, NOIRQ                ; IrqV   * &02
Jeffrey Lee's avatar
Jeffrey Lee committed
533
   & 0, ZeroPage+OsbyteVars, PMFWrch ; WrchV  * &03
Neil Turton's avatar
Neil Turton committed
534 535 536

   & 0, 0, NewRdch              ; RdchV  * &04  - start of VecNo=SWINo section
   & 0, 0, VecOsCli
Jeffrey Lee's avatar
Jeffrey Lee committed
537 538
   & 0, ZeroPage+OsbyteVars, OsByte
   & 0, ZeroPage+OsbyteVars, OsWord
Neil Turton's avatar
Neil Turton committed
539 540 541 542 543 544
   & 0, 0, NaffVector             ; filev
   & 0, 0, NaffVector             ; argsv
   & 0, 0, NaffVector             ; bgetv
   & 0, 0, NaffVector             ; bputv
   & 0, 0, NaffVector             ; gbpbv
   & 0, 0, NaffVector             ; findv
Jeffrey Lee's avatar
Jeffrey Lee committed
545
   & 0, ZeroPage+OsbyteVars, VecRdLine ; ReadlineV  * &0E - end of VecNo=SWINo
Neil Turton's avatar
Neil Turton committed
546 547 548

   & 0, 0, NaffVector           ; fscv

Jeffrey Lee's avatar
Jeffrey Lee committed
549
   & 0, ZeroPage+EvtHan_ws, DefEvent ; EventV * &10
Neil Turton's avatar
Neil Turton committed
550 551 552 553 554 555 556 557 558 559 560 561

   & 0, 0, NaffVector           ; UPTV   * &11
   & 0, 0, NaffVector           ; NETV   * &12

   & 0, 0, KeyVector            ; KEYV   * &13

   & 0, BuffParms+0, NewInsV    ; INSV   * &14
   & 0, BuffParms+0, NewRemV    ; REMV   * &15
   & 0, BuffParms+4, NewCnpV    ; CNPV   * &16     ; Count/Purge Buffer V

   & 0, 0, NaffVector           ; UKVDU23V * &17   ; ---| VDU23 (decimal)

Jeffrey Lee's avatar
Jeffrey Lee committed
562
   & 0, ZeroPage+HiServ_ws, HighSWI ; UKSWIV   * &18   ; ---| Unknown SWI numbers
Neil Turton's avatar
Neil Turton committed
563 564 565 566 567 568 569 570

   & 0, 0, NaffVector           ; UKPLOTV  * &19   ; ---| VDU25 (decimal)

   & 0, 0, ReadMouse            ; MouseV * &1A

   & 0, 0, NaffVector           ; VDUXV   * &1B
   & 0, 0, Def_100HZ            ; TickerV * &1C

Jeffrey Lee's avatar
Jeffrey Lee committed
571
   & 0, ZeroPage+UpCallHan_ws, CallUpcallHandler
Neil Turton's avatar
Neil Turton committed
572 573 574
                                ; UpCallV * &1D
   & 0, 0, AdjustOurSet         ; ChangeEnvironment * &1E

Jeffrey Lee's avatar
Jeffrey Lee committed
575
   & 0, ZeroPage+VduDriverWorkSpace, SpriteVecHandler ; SpriteV * &1F
Neil Turton's avatar
Neil Turton committed
576 577 578
   & 0, 0, NaffVector           ; DrawV * &20
   & 0, 0, NaffVector           ; EconetV * &21
   & 0, 0, NaffVector           ; ColourV * &22
Jeffrey Lee's avatar
Jeffrey Lee committed
579
   & 0, ZeroPage+VduDriverWorkSpace, MOSPaletteV ; PaletteV * &23
Neil Turton's avatar
Neil Turton committed
580 581 582 583
   & 0, 0, NaffVector           ; SerialV * &24

   & 0, 0, NaffVector           ; FontV * &25

584
   & 0, 0, PointerVector        ; PointerV * &26
Kevin Bracey's avatar
Kevin Bracey committed
585 586
   & 0, 0, NaffVector           ; TimeCodeV * &27
   & 0, 0, NaffVector           ; LowPriorityEventV &28
587
   & 0, 0, NaffVector           ; &29
Jeffrey Lee's avatar
Jeffrey Lee committed
588
   & 0, ZeroPage+VduDriverWorkSpace, MOSGraphicsV  ; GraphicsV * &2a
589
   & 0, 0, NaffVector           ; UnthreadV * &2b
590
   & 0, 0, NaffVector           ; SeriousErrorV * &2c
Neil Turton's avatar
Neil Turton committed
591 592 593 594 595 596 597 598 599 600

 ; the spares
   & 0, 0, NaffVector           ; &2d
   & 0, 0, NaffVector           ; &2e
   & 0, 0, NaffVector           ; &2f

 assert (.-defaultvectab) = NVECTORS*VecNodeSize

NaffVector ROUT
Def_100HZ
601
        MRS     lr, CPSR
Kevin Bracey's avatar
Kevin Bracey committed
602
        BIC     lr, lr, #V_bit
603
        MSR     CPSR_f, lr              ; Clear V, preserve rest
Kevin Bracey's avatar
Kevin Bracey committed
604
        LDR     pc, [sp], #4            ; Claim vector, do nowt
Neil Turton's avatar
Neil Turton committed
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; SWIs to save any vector entries pointing into application workspace
;
; Delink SWI:
;   R0 pointer to buffer
;   R1 buffer size
; Returns R1 bytes left in buffer
;   V set if buffer not large enough

Application_Delink ROUT
      Push "R0, R2-R4, lr"

      CMP   R1, #4
      BLT   %FT99                   ; invalid buffer size

Jeffrey Lee's avatar
Jeffrey Lee committed
621
    [ ZeroPage = 0
Neil Turton's avatar
Neil Turton committed
622 623
      MOV   R3, #NVECTORS-1
      LDR   R4, [R3, #AplWorkSize-(NVECTORS-1)]
Jeffrey Lee's avatar
Jeffrey Lee committed
624 625 626 627 628
    |
      LDR   R4, =ZeroPage
      MOV   R3, #NVECTORS-1
      LDR   R4, [R4, #AplWorkSize]
    ]
629
      SETPSR I_bit, R2           ; IRQs off while holding context.
Neil Turton's avatar
Neil Turton committed
630

Jeffrey Lee's avatar
Jeffrey Lee committed
631
03    LDR   R11, =ZeroPage+VecPtrTab ; Point at table of head pointers
Neil Turton's avatar
Neil Turton committed
632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647
      ADD   R10, R11, R3, LSL #2
04    MOV   R11, R10             ; step chain
      LDR   R10, [R11]
05    CMP   R10, #0
      BNE   %FT02
      SUBS  R3, R3, #1
      BPL   %BT03                ; next vector
      MOV   R3, #-1
      STR   R3, [R0]
      SUB   R1, R1, #4
      Pull "R0, R2-R4, lr"
      ExitSWIHandler

02    LDR   R12, [R10, #Address]
      CMP   R12, R4
      BGT   %BT04
648
      CMP   R12, #AppSpaceStart
Neil Turton's avatar
Neil Turton committed
649 650 651 652 653 654 655 656 657 658 659 660 661 662 663
      BLT   %BT04

; appl entry found: put in buffer, free it
      CMP   R1, #12+4
      BLT   %FT99                ; no rheum
      LDR   R14, [R10, #VecWSpace]
      STMIA R0!, {R3, R12, R14}
      SUB   R1, R1, #12          ; buffer entry added

      LDR   R12, [R10, #TailPtr]
      STR   R12, [R11]           ; vector delinked

        Push    "R0-R2"
        MOV     R2, R10
        MOV     R10, R12                        ; keep updated thisblk
664 665
  [ ChocolateSysHeap
        ASSERT  ChocolateSVBlocks = ChocolateBlockArrays + 4
Jeffrey Lee's avatar
Jeffrey Lee committed
666
        LDR     r1,=ZeroPage+ChocolateBlockArrays
667 668 669 670
        LDR     r1,[r1,#4]
        BL      FreeChocolateBlock
        BLVS    FreeSysHeapNode
  |
Neil Turton's avatar
Neil Turton committed
671
        BL      FreeSysHeapNode
672
  ]
Neil Turton's avatar
Neil Turton committed
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
        MOVVS   lr, R0
        Pull    "R0-R2"
        BVC     %BT05

98    STR   lr, [stack]
      MOV   R3, #-1               ; terminate buffer even if error
      CMP   r1, #4
      STRGE R3, [R0]
      SUB   R1, R1, #4
      Pull "R0, R2-R4, lr"
      B    SLVK_SetV

99
    [ International
      Push  "r0"
      ADRL  r0, ErrorBlock_BuffOverflow
      BL    TranslateError
      MOV   lr,r0
      Pull  "r0"
    |
      ADRL  lr, ErrorBlock_BuffOverflow
    ]
      B     %BT98

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Relink SWI:
;   R0 pointer to buffer as set by Delink
; Returns V set if can't relink all

Application_Relink ROUT
703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723
 [ {TRUE}
; Run through the buffer BACKWARDS to ensure that the vectors are
; reinstalled in the same order.
      Push   "R0-R3, lr"
      MOV     R3, R0            ; R3 -> start of buffer
      MOV     R10, R0
01    LDR     R0, [R10], #12    ; search forwards to find terminator
      CMP     R0, #-1
      BNE     %BT01
      SUB     R10, R10, #12     ; R10 -> terminator
02    CMP     R10, R3           ; loop backwards until we get to start
      Pull   "R0-R3, lr", EQ
      ExitSWIHandler EQ

      LDMDB   R10!, {R0-R2}
      SWI     XOS_AddToVector
      BVC     %BT02
      STR     R0, [stack]
      Pull   "R0-R3, lr"
      B      SLVK_SetV
 |
Neil Turton's avatar
Neil Turton committed
724 725 726 727 728 729 730 731 732 733 734 735 736
      Push   "R0-R2, lr"
      MOV     R10, R0
02    LDR     R0, [R10], #4
      CMP     R0, #-1
      Pull   "R0-R2, lr", EQ
      ExitSWIHandler EQ

      LDMIA   R10!, {R1, R2}
      SWI     XOS_AddToVector
      BVC     %BT02
      STR     R0, [stack]
      Pull   "R0-R2, lr"
      B      SLVK_SetV
737
 ]
Neil Turton's avatar
Neil Turton committed
738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760

;********************************************************************
; Now the stuff that issues service calls; also deals with the MOS
;  being default default FIQ owner, and wanting to see application
;  startup.
;********************************************************************

        GBLL  DebugNeil
DebugNeil SETL {FALSE}          ; if TRUE, check R7-R11 preserved over services

Issue_Service ROUT             ; R1 is service number, R2 may be a parameter
                               ; registers preserved.
       Push    "R9-R12, lr"

       CMP      R1, #Service_ClaimFIQ
       CMPNE    R1, #Service_ClaimFIQinBackground
       BEQ      FIQclaim
       CMP      R1, #Service_ReleaseFIQ
       BEQ      test_FIQclaim_in_progress

       CMP      r1, #Service_NewApplication
       BEQ      checkmoshandlers

761 762 763 764 765
  [ ChocolateService
05
       CMP      R1,#ServMinUsrNumber
       BHS      %FT84
;call anyone on the appropriate Sys chain
Jeffrey Lee's avatar
Jeffrey Lee committed
766
       LDR      R10,=ZeroPage
Kevin Bracey's avatar
Kevin Bracey committed
767
       LDR      R10,[R10,#Serv_SysChains]
768 769 770 771 772 773 774 775 776 777 778 779 780
       CMP      R10,#0
       BEQ      %FT88
       LDR      R11,[R10,R1,LSL #2]             ;pick up the chain anchor
80
;call everyone on the chain, passing R1 value from chain if appropriate
       CMP      R11,#0
       BEQ      %FT88
       LDR      R10,[R11,#ServChain_Size]
       ADD      R11,R11,#ServChain_HdrSIZEOF    ;start of chain
       ADD      R10,R10,R11                     ;end of chain
82
       CMP      R11,R10
       BHS      %FT88
781

782 783 784 785 786 787 788
       Push     "R10"
       MOV      R10,R1
       LDR      R9,[R11,#ServEntry_R1]
       TEQ      R9,#0                           ; 0 means pass service number as normal
       MOVNE    R1,R9                           ; else pass R1 value from chain (will be service index)
       LDR      R12,[R11,#ServEntry_WSpace]
       LDR      R9,[R11,#ServEntry_Code]
789
     [ NoARMv5
790 791
       MOV      lr, pc                          ; link inc. PSR, mode
       MOV      pc, R9
792 793 794
     |
       BLX      R9
     ]
795 796 797 798 799 800 801 802 803
       CMP      R1, #Service_Serviced
       MOVNE    R1,R10                          ; restore R1 unless claimed
       Pull     "R10"
       BEQ      %FT01
       ADD      R11,R11,#ServEntry_SIZEOF
       B        %BT82
;
;call anyone on the appropriate Usr chain
84
Jeffrey Lee's avatar
Jeffrey Lee committed
804
       LDR      R10,=ZeroPage+Serv_UsrChains
805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826
       LDR      R10,[R10]
       CMP      R10,#0
       BEQ      %FT88
       ServHashFunction R9,R1
       LDR      R11,[R10,R9,LSL #2]             ;pick up the chain-array anchor
       CMP      R11,#0
       BEQ      %FT88
       LDR      R10,[R11,#ServUChArray_Size]
       ADD      R11,R11,#ServUChArray_HdrSIZEOF ;start of list
       ADD      R10,R10,R11                     ;end of list
86
       CMP      R11,R10
       BHS      %FT88
       LDR      R9,[R11,#ServUChEntry_ServiceNo]
       TEQ      R9,R1
       ADDNE    R11,R11,#ServUChEntry_SIZEOF
       BNE      %BT86
       LDR      R11,[R11,#ServUChEntry_ChainAnchor]  ;found chain for this service number
       B        %BT80
;
;call everyone on the chain of Awkward modules, always passing service number in R1
88
Jeffrey Lee's avatar
Jeffrey Lee committed
827
       LDR      R10,=ZeroPage
Kevin Bracey's avatar
Kevin Bracey committed
828
       LDR      R11,[R10,#Serv_AwkwardChain]
829 830 831 832 833 834 835 836 837 838
       CMP      R11,#0
       BEQ      %FT01
       LDR      R10,[R11,#ServChain_Size]
       ADD      R11,R11,#ServChain_HdrSIZEOF    ;start of chain
       ADD      R10,R10,R11                     ;end of chain
90
       CMP      R11,R10
       BHS      %FT01
       LDR      R12,[R11,#ServEntry_WSpace]
       LDR      R9,[R11,#ServEntry_Code]
839
     [ NoARMv5
840 841
       MOV      lr, pc                          ; link inc. PSR, mode
       MOV      pc, R9
842 843 844
     |
       BLX      R9
     ]
845 846 847 848 849 850 851
       CMP      R1, #Service_Serviced
       BEQ      %FT01
       ADD      R11,R11,#ServEntry_SIZEOF
       B        %BT90

  | ;IF/ELSE ChocolateService

Jeffrey Lee's avatar
Jeffrey Lee committed
852
05     LDR      R10, =ZeroPage+Module_List
Neil Turton's avatar
Neil Turton committed
853 854 855 856 857 858 859
03     LDR      R10, [R10, #Module_chain_Link]
       CMP      R10, #0
       BEQ      %FT01
       LDR      R9, [R10, #Module_code_pointer]
       LDR      R11, [R9, #Module_Service]
       CMP      R11, #0
       BEQ      %BT03
860 861 862 863 864
 [ DebugROMPostInit
       CMP      R1, #Service_PostInit           ; If it is a Service_PostInit call
       BEQ      display_pre_postinit_calls      ; Go and display the postinit call
83
 ]
Neil Turton's avatar
Neil Turton committed
865 866 867 868 869 870 871 872 873 874 875
       ADD      R9, R9, R11
       ADD      R11, R10, #Module_incarnation_list - Incarnation_Link
04     LDR      R11, [R11, #Incarnation_Link]
       CMP      R11, #0
       BEQ      %BT03

       [ DebugNeil
       Push     "R7-R11"
       ]

       ADD      R12, R11, #Incarnation_Workspace
876
     [ NoARMv5
Neil Turton's avatar
Neil Turton committed
877 878
       MOV      lr, pc               ; link inc. PSR, mode
       MOV      pc, R9
879 880 881
     |
       BLX      R9
     ]
Neil Turton's avatar
Neil Turton committed
882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897

       [ DebugNeil
       ! 0, "Debug code included to check R7-R11 are preserved over services"
       MOV      lr, sp
       Push     "R1-R5"
       LDMIA    lr, {R1-R5}
       TEQ      R1, R7
       TEQEQ    R2, R8
       TEQEQ    R3, R9
       TEQEQ    R4, R10
       TEQEQ    R5, R11
       MOVNE    PC, #0
       Pull     "R1-R5"
       ADD      sp, sp, #5*4
       ]

898 899 900 901 902 903
 [ DebugROMPostInit
       CMP      R1, #Service_PostInit           ; If it is a Service_PostInit call
       BEQ      display_post_postinit_calls     ; Go and display the postinit call
87
 ]

Neil Turton's avatar
Neil Turton committed
904 905 906 907
       CMP      R1, #Service_Serviced
       BNE      %BT04
       Pull    "R9-R12, PC"

908 909
  ] ;ChocolateService

Neil Turton's avatar
Neil Turton committed
910 911 912 913
01     CMP      R1, #Service_ReleaseFIQ
       Pull    "R9-R12, PC",NE

     assert (Service_ReleaseFIQ :AND: &FF) <> 0
Jeffrey Lee's avatar
Jeffrey Lee committed
914
     [ ZeroPage = 0
Kevin Bracey's avatar
Kevin Bracey committed
915 916
       LDRB     R9, [R1, #MOShasFIQ-Service_ReleaseFIQ]
       STRB     R1, [R1, #MOShasFIQ-Service_ReleaseFIQ]
Jeffrey Lee's avatar
Jeffrey Lee committed
917 918 919 920 921 922
     |
       LDR      R1, =ZeroPage+MOShasFIQ
       ASSERT ((ZeroPage+MOShasFIQ) :AND: 255) <> 0
       LDRB     R9, [R1]
       STRB     R1, [R1]
     ]
Kevin Bracey's avatar
Kevin Bracey committed
923 924
       TEQ      R9, #0
       BNE      %FT06
Kevin Bracey's avatar
Kevin Bracey committed
925 926 927

       ADR      R1, FIQKiller
       MOV      R10, #FIQKiller_ws - FIQKiller
Jeffrey Lee's avatar
Jeffrey Lee committed
928
       LDR      R11, =ZeroPage+&1C
Kevin Bracey's avatar
Kevin Bracey committed
929 930 931 932
04     LDR      LR, [R1], #4
       SUBS     R10, R10, #4
       STR      LR, [R11], #4
       BNE      %BT04
Jeffrey Lee's avatar
Jeffrey Lee committed
933 934 935
     [ ZeroPage <> 0
       LDR      R10, =ZeroPage
     ]
Kevin Bracey's avatar
Kevin Bracey committed
936 937 938 939
       AddressHAL R10
       LDR      R14, [R9, #-(EntryNo_HAL_FIQDisableAll+1)*4]
       STMIA    R11, {R9, R14}
       Push     "R0"
Jeffrey Lee's avatar
Jeffrey Lee committed
940 941
       LDR      R0, =ZeroPage
       ADD      R1, R0, #&100
Kevin Bracey's avatar
Kevin Bracey committed
942
       ARMop    IMB_Range,,,R0
Kevin Bracey's avatar
Kevin Bracey committed
943
       Pull     "R0"
Kevin Bracey's avatar
Kevin Bracey committed
944

Neil Turton's avatar
Neil Turton committed
945 946 947 948 949
                                        ; MOS is default owner if nobody
06     MOV      R1, #Service_Serviced   ; else wants it.
       Pull    "R9-R12, PC"

FIQclaim
Jeffrey Lee's avatar
Jeffrey Lee committed
950
       LDR      R10, =ZeroPage
Neil Turton's avatar
Neil Turton committed
951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967

  ; first refuse request if a claim is currently in action

       LDRB     R9, [R10, #FIQclaim_interlock]
       CMP      R9, #0
       Pull    "R9-R12, PC",NE                 ; no can do

; have to issue a genuine FIQ claim call: set interlock to prevent another
; one passing round at an awkward moment.

       MOV      r9, #1
       STRB     r9, [r10, #FIQclaim_interlock]

; now safe to inspect our FIQ state

       LDRB     R9, [R10, #MOShasFIQ]
       CMP      R9, #0
Jeffrey Lee's avatar
Jeffrey Lee committed
968
       ASSERT   (ZeroPage :AND: 255) = 0
Neil Turton's avatar
Neil Turton committed
969 970 971
       STRNEB   R10, [R10, #MOShasFIQ]
       MOVNE    r1, #Service_Serviced
fakeservicecall
Robert Sprowson's avatar
Robert Sprowson committed
972
        ; do it this way to cope with ARM v4/v3 differences on storing PC
Neil Turton's avatar
Neil Turton committed
973 974 975
       SUBEQ    stack,stack,#20
       STREQ    PC,[stack,#16]
       BEQ      %BT05
Kevin Bracey's avatar
Kevin Bracey committed
976
       MOV      r0, r0
Jeffrey Lee's avatar
Jeffrey Lee committed
977
       LDR      r10, =ZeroPage
Neil Turton's avatar
Neil Turton committed
978
       LDRB     r9, [r10, #FIQclaim_interlock]
979
       ASSERT   (ZeroPage :AND: 255) = 0
Neil Turton's avatar
Neil Turton committed
980 981 982 983 984 985 986 987 988 989 990 991 992 993 994
       STRB     r10, [r10, #FIQclaim_interlock]

       CMP      r9, #1                         ; test for background release
; if background release happened, there are 3 possibilities:
;   foreground claim; this is defined to have succeeded. Discard release
;   background claim, that succeeded: releaser gave it away anyway. Discard
;       "        "     "   failed; we are holding a giveaway of FIQ, therefore
;                                  claim service call!
; therefore, if background release happened, always claim the service.

       MOVNE    r1, #Service_Serviced
       Pull    "r9-r12, PC"                    ; all done

test_FIQclaim_in_progress

Jeffrey Lee's avatar
Jeffrey Lee committed
995
       LDR      r10, =ZeroPage
Neil Turton's avatar
Neil Turton committed
996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009
       LDRB     r9, [r10, #FIQclaim_interlock]
       CMP      r9, #0

       MOVEQ    r9, #1
       STREQB   r9, [r10, #FIQclaim_interlock] ; lock out background calls
       BEQ      fakeservicecall                ; issue call, clear flag

       MOV      r9, #2                         ; mark release as occurring

       STRB     r9, [r10, #FIQclaim_interlock]
       Pull    "r9-r12, PC"

; r9-r12, lr corruptible
checkmoshandlers
Jeffrey Lee's avatar
Jeffrey Lee committed
1010
     [ ZeroPage = 0
Neil Turton's avatar
Neil Turton committed
1011
       LDR      r9, [r1, #SExitA-Service_NewApplication]
Jeffrey Lee's avatar
Jeffrey Lee committed
1012 1013 1014 1015
     |
       LDR      r9, =ZeroPage
       LDR      r9, [r9, #SExitA]
     ]
Neil Turton's avatar
Neil Turton committed
1016 1017 1018 1019 1020 1021 1022 1023 1024
       ADRL     r10, CLIEXIT
       CMP      r9, r10
       BNE      %BT05
       Push    "r0-r7"
       BL       DEFHAN
       BL       DEFHN2
       Pull    "r0-r7"
       B        %BT05

1025 1026 1027 1028 1029 1030 1031
 [ DebugROMPostInit
 ; Display the title of the current module in the chain.
 ; R9 contains the module pointer.
display_pre_postinit_calls
       SWI     XOS_WriteS
       =       "postinit service call to mod ",0
       Push    "r0-r7"
Robert Sprowson's avatar
Robert Sprowson committed
1032
       LDR     R0, [R9, #Module_TitleStr]
1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049
       ADD     R0, R9, R0
       SWI     XOS_Write0
       SWI     XOS_WriteS
       =       " sent"
       SWI     XOS_NewLine
       Pull    "r0-r7"
       B        %BT83

 ; Display a message stating that we have finished the postinit service call.
 ; This will appear once for every module called on postinit.
display_post_postinit_calls
       SWI     XOS_WriteS
       =       "returned from postinit service call.",0
       SWI     XOS_NewLine
       B        %BT87
 ]

Kevin Bracey's avatar
Kevin Bracey committed
1050 1051
FIQKiller
       SUB     R14, R14, #4
Jeffrey Lee's avatar
Jeffrey Lee committed
1052
       ADR     R13, FIQKiller-&1C+&100
Kevin Bracey's avatar
Kevin Bracey committed
1053 1054 1055 1056
       ADR     R10, FIQKiller_ws
       STMFD   R13!, {R0-R3,R14}
       MOV     R14, PC
       LDMIA   R10, {R9,PC}
1057
       MyCLREX R0, R1
Kevin Bracey's avatar
Kevin Bracey committed
1058 1059 1060
       LDMFD   R13!, {R0-R3,PC}^
FIQKiller_ws

1061

Neil Turton's avatar
Neil Turton committed
1062 1063 1064 1065
;************************************************
; SWI to call a vector
;************************************************
CallAVector_SWI  ; R9 is the vector number (!!)
Kevin Bracey's avatar
Kevin Bracey committed
1066
       STR       lr, [sp, #-4]!         ; save caller PSR on stack
Neil Turton's avatar
Neil Turton committed
1067
       MOV       R10, R9
1068
       MSR       CPSR_f, R12            ; restore caller CCs (including V)
Neil Turton's avatar
Neil Turton committed
1069
       BL        CallVector
1070
       MRS       r10, CPSR              ; restore CCs
Kevin Bracey's avatar
Kevin Bracey committed
1071
       LDR       lr, [sp], #4
1072
     [ NoARMT2
Kevin Bracey's avatar
Kevin Bracey committed
1073
       AND       r10, r10, #&F0000000
Neil Turton's avatar
Neil Turton committed
1074
       BIC       lr, lr, #&F0000000
Kevin Bracey's avatar
Kevin Bracey committed
1075
       ORR       lr, lr, r10
1076 1077 1078 1079
     |
       MOV       r10, r10, LSR #28
       BFI       lr, r10, #28, #4
     ]
Neil Turton's avatar
Neil Turton committed
1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100
       ExitSWIHandler

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

; Now some bits for the dynamic areas

DoSysHeapOpWithExtension
       Push   "R0, lr"
       B       IntoSysHeapOp

ClaimSysHeapNode ROUT ; size in R3
       MOV     R0, #HeapReason_Get
       Push   "R0, lr"
IntoSysHeapOp
       LDR     R1, =SysHeapStart
       SWI     XOS_Heap
       Pull   "R0, PC", VC

       LDR     r14, [r0]                   ; look at error number
       TEQ     r14, #ErrorNumber_HeapFail_Alloc
       STRNE   r0, [stack]
1101
       Pull   "r0, PC", NE                 ; can only retry if ran out of room
Neil Turton's avatar
Neil Turton committed
1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 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

       Push    r3                          ; in case extension
       LDR     r1, [stack, #4]
       CMP     r1, #HeapReason_ExtendBlock
       BNE     notsysheapextendblock

       Push   "r5, r6"
       LDR     r5, =SysHeapStart
       LDR     r6, [r5, #:INDEX:hpdbase]
       ADD     r6, r6, r5                  ; free space
       LDR     r1, [r2, #-4]               ; pick up block size
       ADD     r5, r1, r2                  ; block end +4
       SUB     r5, r5, #4                  ; TMD 02-Aug-93: block size includes size field (optimisation was never taken)
       CMP     r5, r6                      ; does block butt against end?
       ADDNE   r3, r3, r1                  ; max poss size needed
       Pull   "r5, r6"

  ; note that this doesn't cope well with a block at the end preceded by a
  ; free block, but tough.

notsysheapextendblock
       LDR     r1, =SysHeapStart
       LDR     R0, hpdbase
       LDR     R1, hpdend
       SUB     R1, R1, R0          ; size left in heap
       SUB     R1, R3, R1          ; size needed
       Pull    r3
       ADD     R1, R1, #8          ; plus safety space.
       MOV     R0, #0
       SWI     XOS_ChangeDynamicArea
       LDRVC   R0, [stack]  ; and retry.
       LDRVC   R1, =SysHeapStart
       SWIVC   XOS_Heap
       Pull   "R0, PC", VC
SysClaimFail
       ADD     stack, stack, #4
       ADR     R0, ErrorBlock_SysHeapFull
     [ International
       BL      TranslateError
     ]
       Pull   "PC"
       MakeErrorBlock  SysHeapFull

;**************************************************************************
;
;       FreeSysHeapNode - Free a node in system heap
;
; in:   R2 -> node to free
;
; out:  R0 = HeapReason_Free or pointer to error if V=1
;       R1 = SysHeapStart
;

1155
FreeSysHeapNode Entry
Neil Turton's avatar
Neil Turton committed
1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167
        MOV     R0, #HeapReason_Free
        LDR     R1, =SysHeapStart
        SWI     XOS_Heap
        EXIT

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

; ValidateAddress_Code
; R0, R1 are limits of address range to check
; return CC for OK, CS for naff

ValidateAddress_Code ROUT
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 1201 1202 1203 1204 1205
        Push    "r0-r3, lr"
        MOV     r2, r1
        MOV     r1, r0
        MOV     r0, #24
        SWI     XOS_Memory
        ; Pre-RISC OS 3.5, OS_ValidateAddress would return OK if the region was:
        ; (a) valid RAM in logical address space
        ; (b) the 2nd mapping of screen memory at the start of physical address space
        ; (c) anything claimed by Service_ValidateAddress
        ;
        ; Post-RISC OS 3.5, OS_ValidateAddress would return OK if the region was:
        ; (a) a dynamic area
        ; (b) screen memory
        ; (c) most special areas
        ; (d) anything claimed by Service_ValidateAddress
        ;
        ; RISC OS Select docs suggest that valid regions for their version are:
        ; (a) dynamic areas, including special areas which have been turned into DAs (e.g. ROM)
        ; (b) some special areas (e.g. zero page)
        ; (c) screen memory
        ; (d) anything claimed by Service_ValidateAddress (example given of sparse DA which uses OS_AbortTrap to map pages on demand)
        ; (e) NOT physically mapped areas (unless screen memory)
        ;
        ; Taking the above into account, our version will behave as follows:
        ; (a) anything completely accessible in any mode, which isn't physically mapped - dynamic areas, special areas, ROM, zero page, etc.
        ; (b) anything completely R/W in user mode, which is completely physically mapped (i.e. screen memory; this check should suffice until we decide on a better way of flagging screen memory/"IO RAM" as valid)
        ; (c) anything claimed by Service_ValidateAddress
        TST     r1, #CMA_Partially_Phys
        MOVEQ   r2, #1
        ANDEQ   r1, r1, #CMA_Completely_UserR+CMA_Completely_UserW+CMA_Completely_PrivR+CMA_Completely_PrivW
        LDRNE   r2, =CMA_Completely_UserR+CMA_Completely_UserW+CMA_Completely_Phys
        ANDNE   r1, r1, r2
        CMP     r1, r2
        BHS     AddressIsValid ; EQ case: At least one completely flag set
                               ; NE case: Flags match required value
        ; OS_Memory check failed, try the service call
        LDMIA   sp, {r2-r3}
        MOV     r1, #Service_ValidateAddress
Neil Turton's avatar
Neil Turton committed
1206
        BL      Issue_Service
1207 1208
        TEQ     r1, #0                  ; EQ => service claimed, so OK
        Pull    "r0-r3,lr"
Neil Turton's avatar
Neil Turton committed
1209 1210 1211 1212 1213
        ORRNE   lr, lr, #C_bit          ; return CS if invalid
        BICEQ   lr, lr, #C_bit          ; return CC if valid
        ExitSWIHandler

AddressIsValid
1214
        Pull    "r0-r3,lr"
Neil Turton's avatar
Neil Turton committed
1215 1216 1217
        BIC     lr, lr, #C_bit
        ExitSWIHandler

1218

Neil Turton's avatar
Neil Turton committed
1219 1220 1221
        LTORG

        END