Wimp09 31.9 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 31 32 33 34 35 36 37 38
; 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.
;
; > Wimp09

;;-----------------------------------------------------------------------------
;; Claim a block big enough for the RMA sprite pool area, then attempt to
;; map the RMA against the ROM working out the difference.
;;
;; Then claim the block so that it is big enough fill in both areas, build
;; the list and then sort it.  Using the OS_HeapSort SWI.
;;
;; in   [baseofsprites] = current RAM sprite area
;;      [baseofromsprites] = current ROM sprite area
;;      [list_at] = address of sorted list / =0 if none
;;      [listsize] = size of sorted list / =0 if none
;;      [addtoolstolist] = 0 if not to / >0 then add tool sprites pool (if present)
;;      [tool_areaCB] = valid control block for adding tool sprites (if required)
;; out  [list_at] = base of sorted list / =0 if none
;;      [list_size] = size of sorted list (aligned to boundary)
;;      [list_end] = real end of list used when scanning for sprite
;;-----------------------------------------------------------------------------

alignvalue      * 64                    ; *MUST* be a Log2 value

        ASSERT  list_size=list_at+4

39
makespritelist Entry   "R0-R4,R8-R9"
Neil Turton's avatar
Neil Turton committed
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72

        LDRB    R3,addtoolstolist
        TEQ     R3,#0                   ; should I add the tool sprites?
        LDRNE   R0,=SpriteReason_ReadAreaCB +&100
        ADRNEL  R1,tool_areaCB
        SWINE   XOS_SpriteOp            ; Yes then decode the RAM based control block
;
        MOV     R8,R3
        Debuga  sprite,"Sprite count for Tools =",R8
;
        LDR     R0,=SpriteReason_ReadAreaCB +&100
        LDR     R1,baseofromsprites
        SWI     XOS_SpriteOp            ; attempt to get number of ROM sprites
;
        ADD     R8,R8,R3                ; add to growing total
        Debuga  sprite,", ROM =",R3
;
        LDRB    R3,addtoolstolist
        TEQ     R3,#0                   ; Adding tool sprites?
        LDREQ   R0,=SpriteReason_ReadAreaCB +&100
        LDREQ   R1,baseofsprites        ; base of RAM area
        SWIEQ   XOS_SpriteOp            ; No then include iconsprites
;
        Debug   sprite,", RAM =",R3
;
        ADD     R3,R8,R3                ; total number of sprites to be obtained
        ADD     R3,R3,#alignvalue -1
        BICS    R3,R3,#alignvalue -1    ; align to nice boundary
        BLEQ    freelist                ; un allocate the list (if null)
        BEQ     %FT60                   ; exit - if null (flag as so)
;
        LDR     R2,list_size
        CMP     R2,R3,LSL #2            ; is the current buffer big enough?
Ben Avison's avatar
Ben Avison committed
73
        BHS     %FT10                   ; if not then skip the new cliam
Neil Turton's avatar
Neil Turton committed
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
;
        BL      freelist                ; release the current list
;
        MOV     R0,#ModHandReason_Claim
        MOV     R3,R3,ASL #2
        BL     XROS_Module              ; attempt to claim

        DebugE  sprite,"Cant allocate list buffer "

        BVS     %FT60                   ; and fall back if failed to get required memory
;
        Debug   sprite,"list buffer allocated at, size:",R2,R3
;
        ADR     R0,list_at
        STMIA   R0,{R2,R3}              ; store bounds of the list away
10
        LDR     R3,list_at              ; R3 -> buffers to store names pointers at

        Debug   sprite,"Start of sprite list: ",R3

        LDRB    R0,addtoolstolist
        TEQ     R0,#0                   ; Adding tool sprites?
        BNE     %FT25                   ; Yes then jump, don't include RAM icon sprites

        LDR     R0,baseofsprites
        LDR     R1,[R0,#saFirst]
        ADD     R1,R1,R0                ; R1 -> first sprite in area
        LDR     R2,[R0,#saNumber]       ; R2 = count for number of sprites
;
        Debug   sprite,"RAM sprites; first, count =",R1,R2
;
20      SUBS    R2,R2,#1
        STRPL   R1,[R3],#4              ; store a pointer away
        LDRPL   R0,[R1,#spNext]
        ADDPL   R1,R1,R0                ; advance to the next sprite
        BPL     %BT20                   ; looping until finished
;
        Debug   sprite,"End of RAM sprite list =",R3
;
25      LDR     R0,baseofromsprites
        LDR     R1,[R0,#saFirst]
115
        ADD     R1,R1,R0                ; R1 -> start of ROM pool
Neil Turton's avatar
Neil Turton committed
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
        LDR     R2,[R0,#saNumber]       ; R2 = counter for number of sprites in area
;
        Debug   sprite,"ROM sprites; first, count =",R1,R2
30
        SUBS    R2,R2,#1                ; decrease counter
        STRPL   R1,[R3],#4              ; store another pointer away
        LDRPL   R0,[R1,#spNext]
        ADDPL   R1,R1,R0                ; advance to next
        BPL     %BT30                   ; looping until finished (bla de bla)
;
        LDRB    R2,addtoolstolist
        TEQ     R2,#0                   ; add the tools area to the list of sprites
        BEQ     %FT35
;
        ADRL    R0,tool_areaCB
        LDR     R1,[R0,#saFirst]
        ADD     R1,R1,R0
        LDR     R2,[R0,#saNumber]
;
        Debug   sprite,"Tool sprites; first, count =",R1,R2
31
        SUBS    R2,R2,#1                ; have we finished copying the pointers yet?
        STRPL   R1,[R3],#4
        LDRPL   R0,[R1,#spNext]
        ADDPL   R1,R1,R0                ; advance to next sprite
        BPL     %BT31                   ; until finished
35
        Debug   sprite,"End of entire list =",R3
;
; Now perform a Heap Sort of the list.
;
        Push    "R3"                    ; storing the top limit away
        LDR     R1,list_at              ; start of list
        SUB     R0,R3,R1
        MOV     R0,R0,ASR #2            ; number of items in list
151 152 153
      [ debugsprprior
        ADRL    R2,checkspritenames     ; comparison routine
      |
Neil Turton's avatar
Neil Turton committed
154
        ADR     R2,checkspritenames     ; comparison routine
155
      ]
Neil Turton's avatar
Neil Turton committed
156 157 158 159
        MOV     R3,WsPtr

        Debug   sprite,"HeapSort: Items, At, Checker =",R0,R1,R2

160 161
        TST     R1,#2_111:SHL:29        ; high address?
        BNE     %FA37
Neil Turton's avatar
Neil Turton committed
162
        SWI     XOS_HeapSort            ; attempt to sort the list
163 164 165 166 167 168 169
        B       %FA39
37      Push    "R7"
        MOV     R7,#0
        SWI     XOS_HeapSort32          ; use new SWI with 32-bit address
        Pull    "R7"

39      Pull    "R3"                    ; restore original boundary for the list
Neil Turton's avatar
Neil Turton committed
170 171 172 173 174 175 176

; Now attempt to remove duplicates by simply scanning down the list from start to
; end.  This we do by checking first to see if we have reached the end, if we
; have then we can exit.  Otherwise we get two pointers if they are the
; same then we block the entire list back down assuming that the first name
; compared is the

177 178 179
      [ SpritePriority
        LDR     R8,baseofhisprites
      |
Neil Turton's avatar
Neil Turton committed
180
        LDR     R8,baseofsprites
181
      ]
Neil Turton's avatar
Neil Turton committed
182 183 184 185 186 187 188
        LDR     R9,[R8,#saEnd]
        LDR     R2,list_at              ; start of the list to be scanned

        Debug   sprite,"HeapSort done, scan the list for duplicates"

40      SUB     R4,R3,R2
        CMP     R4,#8                   ; have we finished yet?
Ben Avison's avatar
Ben Avison committed
189 190
        STRLO   R3,list_end             ; setup the chopping end
        EXIT    LO
Neil Turton's avatar
Neil Turton committed
191 192 193 194 195 196 197 198 199 200

        LDMIA   R2,{R0,R1}
        BL      checkspritenames        ; are the two sprite names the same?
        ADDNE   R2,R2,#4
        BNE     %BT40                   ; loop back until all finished

 [ debugsprite
        ADD     R14,R0,#spName
        DebugS  sprite,"Duplicate:",R14,12
 ]
201
        SUB     R14,R0,R8               ; is first sprite in the RAM low area? (or high-priority if SpritePriority true)
Neil Turton's avatar
Neil Turton committed
202 203 204
        CMP     R14,R9
        ADDCC   R2,R2,#4                ; advance past entry if inside the RAM area, otherwise copy next name over current

205 206 207
      [ SpritePriority
        LDR     R4,[R2]                 ; note address of sprite being removed from list
      ]
Neil Turton's avatar
Neil Turton committed
208 209 210
        MOV     R0,R2                   ; start to copy from
50      CMP     R0,R3                   ; have we finished yet?
        SUBEQ   R3,R3,#4
211
        BEQ     %FT55                   ; looping until all copied (modify the end pointer as required)
Neil Turton's avatar
Neil Turton committed
212 213 214 215 216

        LDR     R1,[R0,#4]
        STR     R1,[R0],#4              ; copy it down
        B       %BT50                   ; loop until the list has been moved

217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
55
      [ SpritePriority
        LDR     R0, preferredpool
        TEQ     R0, #0
        DebugIf EQ, sprprior, "RAM sprites preferred"
        BEQ     %BT40                   ; don't do anything if RAM sprites have priority

        Push    "R8,R9"
        LDR     R8, baseofsprites       ; see if the removed sprite was in the RAM sprite area
        LDR     R9, [R8, #saEnd]
        SUB     R0, R4, R8
        CMP     R0, R9
        Pull    "R8,R9", HS
      [ debugsprprior
        ADDHS   R4, R4, #spName
        DebugSIf HS, sprprior, "This removed sprite was not in RAM area: ", R4, 12
      ]
        BHS     %BT40                   ; don't do anything if removed sprite wasn't in the RAM sprite area

        Push    "R2,R5"
        LDR     R5, [R4, #spNext]       ; size of sprite (== amount to shift later pointers down by)
      [ debugsprprior
        Debug   sprprior, "Deleting sprite from RAM area: addr, size =", R4, R5
        ADD     R4, R4, #spName
        DebugS  sprprior, "- name = ", R4, 12
        SUB     R4, R4, #spName
      ]
        MOV     R0, #512
245
        ORR     R0, R0, #SpriteReason_DeleteSprite
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
        MOV     R1, R8
        MOV     R2, R4
        SWI     XOS_SpriteOp            ; delete the unnecessary sprite

        LDR     R2, list_at             ; go back to beginning of list
56      CMP     R2, R3                  ; have we finished yet?
        Pull    "R2,R5,R8,R9", EQ
        BEQ     %BT40                   ; go back to check next pair of sprites

        LDR     R0, [R2]
        SUB     R1, R0, R8
        CMP     R1, R9
        ADDHS   R2, R2, #4
        BHS     %BT56                   ; this sprite wasn't in the RAM area, so won't have been affected by the deletion
        CMP     R0, R4
        ADDLO   R2, R2, #4
        BLO     %BT56                   ; this sprite was below the deleted sprite, so again no action is required
        SUB     R0, R0, R5
      [ debugsprprior
        ADD     R0, R0, #spName
        DebugS  sprprior, "Realigned sprite:", R0, 12
        SUB     R0, R0, #spName
      ]
        STR     R0, [R2]                ; move pointer down
        ADD     R2, R2, #4
        B       %BT56                   ; check next pointer
      |
        B       %BT40                   ; go back to check next pair of sprites
      ]

Neil Turton's avatar
Neil Turton committed
276 277 278
60      MOV     R0,#-1
        STR     R0,list_at              ; flag as no valid list setup
        STR     R0,list_size
Kevin Bracey's avatar
Kevin Bracey committed
279
        EXIT
Neil Turton's avatar
Neil Turton committed
280 281 282 283 284 285 286 287 288 289

;..............................................................................

; Compare the two sprite names, ensuring case insensitive and truncating
; at the twelth character

; in    R0 -> sprite to compare
;       R1 -> sprite to compare against
; out   NE/EQ GT/LT CS/CC

290
checknames Entry "R0-R4"
Neil Turton's avatar
Neil Turton committed
291 292 293 294 295 296 297 298 299 300 301 302 303 304
        B       %FT05

checkspritenames ALTENTRY

        ADD     R0,R0,#spName           ; ensure pointing at the sprite names
        ADD     R1,R1,#spName
05      MOV     R2,#12                  ; maximum string length = 12 characters

10      LDRB    R3,[R0],#1
        LDRB    R4,[R1],#1              ; get characters
        CMP     R3,#32
        MOVLE   R3,#0
        CMP     R4,#32
        MOVLE   R4,#0                   ; convert to terminators if required
305 306
        ASCII_LowerCase R3,LR
        ASCII_LowerCase R4,LR           ; ensure that the characters are lower case
Neil Turton's avatar
Neil Turton committed
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
        CMP     R3,R4                   ; and that they match
        EXIT    NE                      ; returning if not the same
;
        TEQ     R3,#0                   ; is it the end of the strings?
        SUBNES  R2,R2,#1
        BNE     %BT10                   ; loop back if still characters pending
;
        CMP     R3,R4                   ; compare the final characters
        EXIT


;;-----------------------------------------------------------------------------
;; Free list - attempt to release the list memory if currently allocated.
;;
;; in   [list_at] >0 then release block
;; out  [list_at] [list_size] = 0
;;-----------------------------------------------------------------------------

Kevin Bracey's avatar
Kevin Bracey committed
325
freelist EntryS  "R0-R2"
Neil Turton's avatar
Neil Turton committed
326 327 328 329

        Debug   sprite,"Calling to free sprite list",#list_at
;
        LDR     R2,list_at
Ben Avison's avatar
Ben Avison committed
330 331 332
        CMP     R2,R2,ASR #31           ; is the list memory allocated?
        MOVNE   R0,#ModHandReason_Free
        BLNE    XROS_Module              ; yes, so release it (ignore errors)
Neil Turton's avatar
Neil Turton committed
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
;
        MOV     R2,#0
        STR     R2,list_at
        STR     R2,list_size            ; mark as released
;
        EXITS


;;-----------------------------------------------------------------------------
;; Locate a sprite name setting its pointers to meaningful values.  This routine
;; attempts to binary chop the sprite list created by calling "makespritelist".
;;
;; Based on the algorithm in Knuth; Sorting/Searching, pp 407
;;
;; in   [spritename] --> sprite name
;; out  R2 -> sprite, VS/VC if found/not found
;;-----------------------------------------------------------------------------

351
getspriteaddr Entry "R0-R1,R3-R5"
Neil Turton's avatar
Neil Turton committed
352 353 354 355

        LDR     R0,spritename           ; get pointer to name to compare against
;
        LDR     R2,list_at              ; base of sprite pointerrs
Ben Avison's avatar
Ben Avison committed
356 357
        CMP     R2,R2,ASR #31           ; this may be 0 (not initialised) or -1 (no room)
        BEQ     %FT20
Neil Turton's avatar
Neil Turton committed
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444
        LDR     R3,list_end
        SUB     R3,R3,R2
        SUB     R3,R3,#4
        MOV     R3,R3,ASR #2            ; u = size of list
        MOV     R4,#0                   ; l = 0

10      CMP     R4,R3                   ; if l>u then not found
        BGT     %FT20
;
        ADD     R5,R4,R3
        MOV     R5,R5,ASR #1            ; i = (l+u) /2
;
        LDR     R1,[R2,R5,ASL #2]
        ADD     R1,R1,#spName
;
        BL      checknames
        ADDGT   R4,R5,#1                ; if [R0]>[R1] l = i + 1
        SUBLT   R3,R5,#1                ; if [R0]<[R1] l = i - 1
        BNE     %BT10
;
        LDR     R2,[R2,R5,ASL #2]       ; R2 -> sprite found !!!
        CLRV
        EXIT
20
        MOV     R2,#0                   ;
        SETV                            ; else return 'cos not found V set!
        EXIT


;;-----------------------------------------------------------------------------
;; Handle the opening of the messages file - check first to see if it has
;; already been opened.
;;
;; in   -
;; out  R0 -> 16 byte block for messages (may already be open)
;;-----------------------------------------------------------------------------

GetMessages ROUT

        Push    "R1-R2,LR"
;
        LDR     R0,messages
        CMP     R0,#0                   ; is it open yet?
        BNE     %FT10
;
        ADRL    R0,message_block
        ADR     R1,messfsp
        MOV     R2,#0                   ; let MessageTrans do caching
        SWI     XMessageTrans_OpenFile
        ADRVCL  R0,message_block
        STRVC   R0,messages             ; pointer to messages block

        Debug   err,"Message block @",R0
10
        Pull    "R1-R2,PC"

messfsp = "WindowManager:Messages",0
        ALIGN


;;-----------------------------------------------------------------------------
;; Handle losing the messages file if its already opened.
;;-----------------------------------------------------------------------------

LoseMessages ROUT

        Push    "R0,LR"
;
        LDR     R0,messages
        CMP     R0,#0                   ; is it already open? (clears V)
        SWINE   XMessageTrans_CloseFile
        STRVS   R0,[SP]
;
        MOV     R14,#0
        STR     R14,messages            ; flag as lost (always!)
;
        Pull    "R0,PC"


;;-----------------------------------------------------------------------------
;; QuickLookup - look up token (no buffer), parameters in R4-R7 are optional
;;
;; in   R0 -> token to lookup
;; out  R0 -> text found
;;      R1 = length of text found
;;-----------------------------------------------------------------------------
QuickLookup
445
        Entry   "R2,R3"
Neil Turton's avatar
Neil Turton committed
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
        MOV     R1,R0
        MOV     R2,#0
        MOV     R3,#0
        BL      GetMessages             ; open messages if required
        SWI     XMessageTrans_Lookup
        MOVVC   R0,R2
        MOVVC   R1,R3
        EXIT

;;-----------------------------------------------------------------------------
;; LookupToken - resolve token into user specified buffer (with parameters)
;;
;; in   R0 -> token to lookup
;;      R2 -> buffer
;;      R3 = length of buffer
;;      R4 -> %0 substitution
;;      R5-R7 assumed to be zero
;;-----------------------------------------------------------------------------

465
LookupToken Entry "R1-R7"
Neil Turton's avatar
Neil Turton committed
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 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 555

        MOV     R1,R0                   ; -> token to be used
        B       %FA10

;;------------------------------------------------------------------------------
;; LookupToken1 - lookup token into user specified buffer
;;
;; in   R0 -> token to lookup
;;      R2 -> buffer
;;      R3 = length of buffer
;;------------------------------------------------------------------------------

LookupToken1 ALTENTRY

        MOV     R1,R0
        MOV     R4,#0                   ; justincase!
        MOV     R5,#0
10      MOV     R6,#0
        MOV     R7,#0
        BL      GetMessages             ; open messages if required
        SWI     XMessageTrans_Lookup
        EXIT


;;-----------------------------------------------------------------------------
;; Lookup an error block expanding and then return.
;;
;; in   R0 -> error block
;; out  R0 -> error block and overflow set
;;-----------------------------------------------------------------------------

ErrorLookup ROUT

        Push    "R0-R7,LR"
;
        BL      GetMessages             ; attempt to open the file
        ADDVS   sp,sp,#4
        BVS     %FT10                   ; reporting any errors in the process
;
        MOV     R1,R0                   ; R1 -> control block
        Pull    "R0"                    ; R0 -> error block
        MOV     R2,#0
        MOV     R4,#0                   ; no parameters
        MOV     R5,#0
        MOV     R6,#0
        MOV     R7,#0

 [ debugerr
        Debuga  err,"WimpErrorLookup,r0,r1",R0,R1
        ADD     R14, R0, #4
        DebugS  err," Token:",R14
 ]
        SWI     XMessageTrans_ErrorLookup
10
        Pull    "R1-R7,PC"              ; look it up and then return


;------------------------------------------------------------------------------
; Constants required for message checking routines
;------------------------------------------------------------------------------

messcheck_version       * 284


;;-----------------------------------------------------------------------------
;; Wimp_AddMessages
;;
;; This SWI will add a null terminated list of messages to the list of
;; accepted messages on the current task.  This is really only any use for
;; tasks which know about Wimp >= 284.
;;
;; in   R0 -> list of messages / =0 for none
;; out  -
;;-----------------------------------------------------------------------------

SWIWimp_AddMessages

        MyEntry "AddMessages"

        Debug   msgsel,"Wimp_AddMessages: list ->",R0

        MOVS    R3,R0
        BEQ     ExitWimp                ; if no messages to add then exit

        LDR     R4,taskhandle           ; currently active task

        LDR     R0,[WsPtr,R4]           ; -> task record
        LDR     R0,[R0,#task_wimpver]
        LDR     R1,=messcheck_version
        CMP     R0,R1                   ; is it worth adding to the list?
Ben Avison's avatar
Ben Avison committed
556
        BLHS    addmessages
Neil Turton's avatar
Neil Turton committed
557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572

        B       ExitWimp

;..............................................................................

; Add a list of messages to the messages to the internal task handle specified,
; in doing so we may actually have to allocate a block.
;
; The routine attempts to add the messages at the end and then perform
; a heap sort.  Having first checked for duplicates, this is not a speed
; critical operation (ie. not called on null-event).

; in    R3 -> list of messages / null terminated
;       R4 = internal task handle to add messages to / assumed to be valid
; out   -

573
addmessages Entry "R0-R7"
Neil Turton's avatar
Neil Turton committed
574 575 576 577 578 579 580 581 582 583

        Debug   msgsel,"add messages: list, task =",R3,R4

        MOV     R5,#0
10      LDR     R6,[R3,R5]
        TEQ     R6,#0                   ; end of the list encountered?
        ADDNE   R5,R5,#4
        BNE     %BT10                   ; loop back until finished scanning

        CMP     R5,#0                   ; is there any messages to add?
Kevin Bracey's avatar
Kevin Bracey committed
584
        EXIT    EQ                      ; if not then return without doing anything
Neil Turton's avatar
Neil Turton committed
585 586 587 588 589 590 591 592

        Debug   msgsel,"size of messages list =",R5

; R5 = size of messages list to add / create

        LDR     R4,[WsPtr,R4]           ; get pointer to the task block

        LDR     R2,[R4,#task_messages]
593 594 595
        CMP     R2,#nullptr
        EXIT    EQ                      ; the real fix for the AddMessages-to-task-that-already-wants-them bug
        CMP     R2,#0
Ben Avison's avatar
Ben Avison committed
596
        BNE     addmoremessages         ; add to the list if non-zero, create new block
Neil Turton's avatar
Neil Turton committed
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615

        Push    "R3"
        MOV     R3,R5                   ; size of list to create
        MOV     R0,#ModHandReason_Claim
        BL     XROS_Module              ; attempt to allocate
        Pull    "R3"
        EXIT    VS

        Debug   msgsel,"new message buffer: size, at =",R5,R2

        STR     R2,[R4,#task_messages]
        STR     R5,[R4,#task_messagessize]
        Push    "R2,R5"

20      LDR     R6,[R3],#4
        TEQ     R6,#0
        STRNE   R6,[R2],#4              ; copy a message number
        BNE     %BT20                   ; loop back until all checked

616
        Pull    "R2,R6"
Neil Turton's avatar
Neil Turton committed
617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632
        B       sortmessages            ; ensure they are sorted

;..............................................................................

; add more to the current list - extend the current block by R5 and then
; attempt to add the messages at the end removing duplicates, once
; done shrink the block down to a real size.

; in    R3 -> list of messages to be added
;       R4 -> task record
;       R5 = number of words to append

addmoremessages
        LDR     R1,[R4,#task_messagessize]
        LDR     R2,[R4,#task_messages]  ; current list information

633 634 635 636 637 638 639 640 641 642 643 644
 [ RO4 :LAND: false ; This is too late to do this fix; if the app wants all messages, the the Wimp hasn't allocated a
                    ; messages list, and so addmoremessages doesn't get called. Interestingly, this fix is undone in
                    ; the patches to 4.02...
; MB FIX
; If the current message list has only the 0 terminator in it then the application wants all messages.
; So, don't bother adding these new messages as that will stop all other messages getting through.
	LDR	R14,[R2,#0]
	TEQ	R14,#0
	EXIT	EQ
; end MB FIX
 ]

Neil Turton's avatar
Neil Turton committed
645 646
        Push    "R3"
        MOV     R0,#ModHandReason_ExtendBlock
647
        MOV     r3, r5                  ;  jb/ma 4/1/06 r5 is already the extra space required
Neil Turton's avatar
Neil Turton committed
648 649 650 651 652 653
        BL     XROS_Module              ; attempt to extend it
        Pull    "R3"                    ; preserve the list pointer
        EXIT    VS

        Debug   msgsel,"extended message block at, size =",R2,R1

654
        MOV     R6,R1                   ; extending boundary  (old message size)
Neil Turton's avatar
Neil Turton committed
655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673

30      LDR     R7,[R3],#4              ; get a value from the list
        TEQ     R7,#0
        BEQ     %FT50

        Debug   msgsel,"adding message (check for duplicate) =",R7

        MOV     R0,R1                   ; index to check entries by

40      SUBS    R0,R0,#4
        STRMI   R7,[R2,R6]
        ADDMI   R6,R6,#4                ; add in at the end if end reached
        BMI     %BT30

        LDR     R14,[R2,R0]             ; get a message number
        CMP     R14,R7                  ; does it already exist
        BNE     %BT40                   ; loop back until found
        B       %BT30                   ; if it doesn't then try another entry

John Ballance's avatar
John Ballance committed
674 675 676
50      ADD     r3,r1,r5                ; jb/ma 18/1/06 total needed + claimed
        SUBS    r3,r6,r3                ; jb/ma 18/1/06 actual less above
                                        ; so give back any not needed
677 678
        MOVNE   R0,#ModHandReason_ExtendBlock
        BLNE   XROS_Module              ; reduce back to a meaningful size
Neil Turton's avatar
Neil Turton committed
679 680
        EXIT    VS

681
        Debug   msgsel,"after block truncate: at, change =,size =",R2,R3,R6
Neil Turton's avatar
Neil Turton committed
682

683 684 685
        STR     R2,[R4,#task_messages]  ; update to contain new size
        STR     R6,[R4,#task_messagessize] ; jb/ma 4/1/06 this is the actual size
                                           ; r3 is only the change in size
Neil Turton's avatar
Neil Turton committed
686 687

sortmessages
688
        Debug   msgsel,"sort list at, size =",R2,R6
Neil Turton's avatar
Neil Turton committed
689

690
        MOV     R0,R6,LSR #2            ; size of the list to be sorted
Neil Turton's avatar
Neil Turton committed
691 692
        MOV     R1,R2                   ; -> list to be sorted
        MOV     R2,#0                   ; sorting unsigned integers
693 694
        TST     R1,#2_111:SHL:29
        BNE     %FT55
Neil Turton's avatar
Neil Turton committed
695
        SWI     XOS_HeapSort
696 697 698 699
        B       %FT57
55      MOV     R7,#0
        SWI     XOS_HeapSort32
57
Neil Turton's avatar
Neil Turton committed
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722
        Debug   msgsel,"list sorted and ready to rock and roll"

        EXIT


;;-----------------------------------------------------------------------------
;; Wimp_RemoveMessages
;;
;; Attempt to remove a set of messages being accepted by a task, no errors
;; are generated for unknown messages.  This call only applies to tasks
;; with a version >= 284.
;;
;; in   R0 -> list of messages / =0 for none
;; out  -
;;-----------------------------------------------------------------------------

SWIWimp_RemoveMessages

        MyEntry "RemoveMessages"

        Debug   msgsel,"Wimp_RemoveMessages: list at =",R0

        MOVS    R3,R0                   ; is there a messages list?
723
        CMPNE   R3,#nullptr
724
        BEQ     ExitWimp                ; exit if there is no list supplied
Neil Turton's avatar
Neil Turton committed
725 726 727 728 729 730 731

        LDR     R4,taskhandle

        LDR     R0,[WsPtr,R4]           ; -> task that is currently active
        LDR     R0,[R0,#task_wimpver]   ; = version number known by this task
        LDR     R1,=messcheck_version
        CMP     R0,R1                   ; is the tasks version number valid for this call?
Ben Avison's avatar
Ben Avison committed
732
        BLHS    removemessages
Neil Turton's avatar
Neil Turton committed
733 734 735 736 737 738 739 740 741 742 743

        B       ExitWimp

;..............................................................................

; remove the list of messages at R3 using internal handle of R4.

; in    R3 -> list of messages (will be non-zero)
;       R4 = internal task handle
; out   -

744
removemessages Entry "R1-R2,R4-R8"
Neil Turton's avatar
Neil Turton committed
745 746 747 748 749

        Debug   msgsel,"Selective remove task, list at =",R3,R4

        LDR     R4,[WsPtr,R4]           ; -> task block

750 751
        LDR     R2,[R4,#task_messages]
        CMP     R2,R2,ASR #31           ; are there any messages listed?
752
                                        ; (or does the task need to continue to receive all messages anyway?)
Ben Avison's avatar
Ben Avison committed
753 754 755
        LDRNE   R6,[R4,#task_messagessize]
        CMPNE   R6,#0
        EXIT    EQ                      ; if no messages then return
Neil Turton's avatar
Neil Turton committed
756

757
        Debug   msgsel,"selective remove list, size =",R2,R6
Neil Turton's avatar
Neil Turton committed
758

759
; R2 -> messages list
Neil Turton's avatar
Neil Turton committed
760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775
; R6 = size of the list to be scanned

10      MOV     R7,#0                   ; index into the list

        LDR     R8,[R3],#4              ; get message to be removed
        CMP     R8,#0
        BEQ     %FT40                   ; when end of list reached then reduce block size

        Debug   msgsel,"scan to remove message =",R8

; R7 = index into list of messages being scanned
; R8 = message to be removed

20      CMP     R7,R6                   ; have we reached the end of the list yet?
        BGE     %BT10                   ; loop back as finished scanning

776
        LDR     R0,[R2,R7]              ; get message we are looking at
Neil Turton's avatar
Neil Turton committed
777 778 779 780 781 782 783 784
        CMP     R0,R8                   ; remove this one?
        ADDNE   R7,R7,#4
        BNE     %BT20                   ; loop back until all checked

        Debug   msgsel,"message found at offset =",R7

30      CMP     R7,R6                   ; have we finished yet?
        ADDLT   R14,R7,#4
785 786
        LDRLT   R0,[R2,R14]
        STRLT   R0,[R2,R7]              ; copy the next message into the current slot
Neil Turton's avatar
Neil Turton committed
787 788 789 790 791 792 793 794
        ADDLT   R7,R7,#4                ; advance the pointer
        BLT     %BT30                   ; loop back until all checked

        Debug   msgsel,"message removed: new list size =",R6

        SUB     R6,R6,#4
        B       %BT10                   ; and try again until whole list scanned
40
795 796
        LDR     R3,[R4,#task_messagessize]  ; old size
        STR     R6,[R4,#task_messagessize]  ; new size
797 798
        SUBS    r3,r6,r3                ; jb/ma 4/1/06 check what we did not use
                                        ; and give back any unused
Neil Turton's avatar
Neil Turton committed
799

800 801
        MOVNE   R0,#ModHandReason_ExtendBlock
        BLNE    XROS_Module              ; attempt to reduce the block size
Neil Turton's avatar
Neil Turton committed
802 803
        STRVC   R2,[R4,#task_messages]  ; and then store updated block pointer

804
        Debug   msgsel,"after extend block: size of list =",R2,R6
Neil Turton's avatar
Neil Turton committed
805 806 807 808 809 810 811 812 813 814 815

        EXIT


;;-----------------------------------------------------------------------------
;; Remove all messages allocated to this task - flagging as removed.
;;
;; in   R5 = internal task handle
;; out  -
;;-----------------------------------------------------------------------------

816
removeallmessages Entry "R0,R2,R4-R5"
Neil Turton's avatar
Neil Turton committed
817 818 819 820 821 822

        Debug   msgsel,"remove all messages for task =",R5

        LDR     R5,[WsPtr,R5]           ; -> task record to be modified

        LDR     R2,[R5,#task_messages]
Ben Avison's avatar
Ben Avison committed
823 824 825
        CMP     R2,R2,ASR #31           ; is there a list attached
        MOVNE   R0,#ModHandReason_Free
        BLNE   XROS_Module              ; attempt to release it
Neil Turton's avatar
Neil Turton committed
826 827 828 829 830 831

        MOV     R2,#-1                  ; flag as no list of messages
        STR     R2,[R5,#task_messages]
        MOV     R2,#0
        STR     R2,[R5,#task_messagessize]

Kevin Bracey's avatar
Kevin Bracey committed
832 833
        CLRV
        EXIT
Neil Turton's avatar
Neil Turton committed
834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855


;;------------------------------------------------------------------------------
;; Scan to see if a message is active for the specified task.  This routine
;; must scan using the internal task handle specified and see if we can
;; broadcast to it.
;;
;; The routine takes the destination task handle and looks to see if it
;; has a messages list attached, if the pointer to this list is -1 (default)
;; then it is assumed that all messages are passed through (old style task)
;; otherwise it attempts to binary chop the list to find the required
;; message.
;;
;; in   R2 -> message block
;;      R3 -> task block (known to be alive)
;;      R5 = external task handle
;; out  R5 = R5 AND msf_broadcast
;;              IF R5 =0 on entry or message is not supported
;;------------------------------------------------------------------------------

checkformessage

856
        Entry   "R0-R4"
Neil Turton's avatar
Neil Turton committed
857 858

        LDR     R0,[R3,#task_messages]
859 860 861
        LDR     R1,[R3,#task_messagessize]
        CMP     R0,#nullptr             ; are all messages enabled?
        EXIT    EQ                      ; yes, so send all of them
Neil Turton's avatar
Neil Turton committed
862 863 864 865 866

        Debug   msgsel,"into check for message; block at, task, external =",R2,R3,R5

        LDR     R2,[R2,#ms_action +msb_size]
        TEQ     R2,#Message_Quit        ; message quit is always allowed
Kevin Bracey's avatar
Kevin Bracey committed
867
        EXIT    EQ                      ; so always return ....
Neil Turton's avatar
Neil Turton committed
868 869 870 871

        TEQ     R0,#0                   ; duff list characteristics?
        TEQNE   R1,#0
        ANDEQ   R5,R5,#msf_broadcast
Kevin Bracey's avatar
Kevin Bracey committed
872
        EXIT    EQ                      ; if so then return flaging as don't broadcast - quit already trapped!
Neil Turton's avatar
Neil Turton committed
873 874 875 876 877 878 879 880 881

        Debug   msgsel,"list at, size, msg =",R0,R1,R2

        SUB     R1,R1,#4
        MOV     R1,R1,LSR #2            ; R1 = size of list
        MOV     R3,#0                   ; R3 = l = 0

10      CMP     R1,R3                   ; end of list reached?
        ANDLT   R5,R5,#msf_broadcast
Kevin Bracey's avatar
Kevin Bracey committed
882
        EXIT    LT                      ; yes, so mark as not to be sent and then return
Neil Turton's avatar
Neil Turton committed
883 884 885 886 887 888 889 890 891 892 893 894

        ADD     R4,R1,R3
        MOV     R4,R4,LSR #1            ; get the mid point

        LDR     R14,[R0,R4,LSL #2]      ; get the message at this location
        CMP     R14,R2
        SUBGT   R1,R4,#1
        ADDLT   R3,R4,#1                ; adjust based on result, if equal then don't bother
        BNE     %BT10                   ; looping whilst not found

        Debug   msgsel,"message found =",R14,R2

Kevin Bracey's avatar
Kevin Bracey committed
895
        EXIT
Neil Turton's avatar
Neil Turton committed
896 897 898


        END