Wimp07 104 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 39 40
; 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.
;
; > Sources.Wimp07

;;----------------------------------------------------------------------------
;; Constants used by Wimp_SendMessage
;;----------------------------------------------------------------------------

                ^       0
msb_link        #       4
msb_receiver    #       4
msb_allsender   #       4               ; for R2 on exit from Wimp_Poll
msb_handle      #       4               ; remember window/icon handle
msb_reasoncode  #       4
msb_size        #       4               ; is also size of header!
msb_sender      #       4
msb_myref       #       4
msb_yourref     #       4               ; ms_xxx defined in Hdr.Messages

ms_sender       *       ms_taskhandle   ; for convenience!

min_messsize    *       ms_data         ; only applies to 17,18,19
max_messsize    *       256

msf_broadcast   *       1:SHL:31

MSToWimpMagicHandle     *       &706d6957       ; Reads "Wimp" in *memoryi, is not word aligned and has top bit (msf_broadcast) clear

Neil Turton's avatar
Neil Turton committed
41 42 43 44 45 46 47 48 49
        MACRO
$lab    CheckMsgQ
$lab
      [ NKmessages1
        LDR     R0,lastpointer
        SUBS    R0,R0,R2
        STREQ   R0,lastpointer
      ]
        MEND
Neil Turton's avatar
Neil Turton committed
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

;;----------------------------------------------------------------------------
;; Return Message to task (called by Wimp_Poll)
;; Entry:  R2 --> message to send (same as [headpointer]
;;         [headpointer] --> message blocks (linked list)
;; Exit:   [taskhandle] set up
;;         message block removed from list, if necessary
;;         code branches to ExitPoll, unless task dead or code is masked out
;;         broadcast messages of type 12:
;;           if any task acknowledges it, no more tasks get the broadcast
;;           if no tasks acknowledge it, the block is returned to sender
;;           - the code seems to have dropped out nicely !!!
;; Note:
;;         if a task or window has been subsequently deleted,
;;           the message is not delivered (returned if appropriate)
;;----------------------------------------------------------------------------

returnmessage
        [ debugpk
        LDR     R5,[R2,#msb_receiver]
        MOV     R5,R5,LSL #16
        LDR     R14,=&16840000
        TEQ     R14,R5
        BNE     glurg
        LDR     R14,[R2,#msb_reasoncode]        ; if its a message then checking
        LDR     R5,[R2,#msb_allsender]

        Debug   pk,"About to send message to TM ",R14,R5
        LDR     R14,[R2,#msb_link]
Ben Avison's avatar
Ben Avison committed
79 80
        CMP     R14,#nullptr
        BEQ     glurg
Neil Turton's avatar
Neil Turton committed
81 82 83 84 85 86 87

        LDR     R5,[R14,#msb_receiver]

        LDR     R14,[R14,#msb_reasoncode]
        Debug   pk,"Next reason code message is ",R14,R5

        LDR     R14,[R2,#msb_link]
Ben Avison's avatar
Ben Avison committed
88 89
        CMP     R14,#nullptr
        BEQ     glurg
Neil Turton's avatar
Neil Turton committed
90
        LDR     R14,[R14,#msb_link]
Ben Avison's avatar
Ben Avison committed
91 92
        CMP     R14,#nullptr
        BEQ     glurg
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


        LDR     R14,[R14,#msb_reasoncode]
        Debug   pk,"And the next is is ",R14

glurg
        ]

;
; set up 'sender', so ExitPoll can return R2 = sender's handle if necessary
;
        LDR     R14,[R2,#msb_allsender]
        STR     R14,sender
;
; page in appropriate task - if doing broadcast, update count
;
        LDR     R5,[R2,#msb_receiver]


        TST     R5,#msf_broadcast
        ADDNE   R14,R5,#4                       ; on to next task
        STRNE   R14,[R2,#msb_receiver]
        LDRNE   R0,=maxtaskhandle:OR:msf_broadcast
        CMPNE   R14,R0
        BICCS   R5,R5,#msf_broadcast            ; last one is just 'ordinary'
;
; if the task has died, don't send the message !!!
;
        TEQ     R5,#0                   ; if zero, don't send message
        BEQ     %FT01
;
; Catch messages to Wimp
;


        LDR     R14,=MSToWimpMagicHandle
        TEQ     R5,R14
        BEQ     autowimp_menu
Kevin Bracey's avatar
Kevin Bracey committed
131

Neil Turton's avatar
Neil Turton committed
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 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
        MOV     R14,R5,LSL #32-flag_versionbit
        LDR     R3,[wsptr,R14,LSR #32-flag_versionbit]  ; R3 --> task data
        TST     R3,#task_unused
        BNE     %FT01                           ; give up now!
;
        LDR     R14,[R2,#msb_reasoncode]        ; if its a message then checking

        CMP     R14,#User_Message
        CMPNE   R14,#User_Message_Recorded
        CMPNE   R14,#User_Message_Acknowledge
        BLEQ    checkformessage
;
        LDR     R3,[R3,#task_flagword]          ; R3 = flag word (if not dead)
        BIC     R14,R5,#msf_broadcast
        MOVS    R14,R14,LSR #flag_versionbit    ; if version bits set,
        TEQNE   R14,R3,LSR #flag_versionbit     ; ensure they are the same!
        MOVEQ   R14,#1
        LDREQ   R0,[R2,#msb_reasoncode]
        TSTEQ   R3,R14,LSL R0           ; check whether this code is masked out
01
        ANDNE   R5,R5,#msf_broadcast    ; mark lower bits 0 ==> don't send it!

;
; R5 (bits 0..19) = 0 ==> don't send message
;
        MOV     R14,R5,LSL #32-flag_versionbit
        MOVS    R14,R14,LSR #32-flag_versionbit
        BEQ     postposting
;
        Task    R14,,"Message return"           ; page in appropriate task
        ADD     R1,R2,#msb_size                 ; R1 --> actual message bit
        BL      calcmessagesize                 ; R3 = size of message block
        BVS     ExitPoll
;
        Debug   ms,"Message: task,rc,R1,size =",#taskhandle,R0,userblk,R3
        TEQ     R3,#0
        BEQ     postposting
        MOV     R4,userblk
01
        LDR     R14,[R1],#4                     ; copy into [userblk]
        STR     R14,[R4],#4
        SUBS    R3,R3,#4
        BNE     %BT01
;
; having copied the block out, decide whether to free the heap block
;
postposting
        TST     R5,#msf_broadcast               ; if broadcast,
        BNE     doneblock                       ; keep the block
;
        LDR     R0,[R2,#msb_reasoncode]         ; (may not have been loaded)
        TEQ     R0,#User_Message_Recorded       ; unless recorded,
        BEQ     %FT01                           ; delete block
;
        LDR     R14,[R2,#msb_link]
        STR     R14,headpointer
;
        Debug   ms,"Freeing block at:",R2
        Push    "R0"
Neil Turton's avatar
Neil Turton committed
191
        CheckMsgQ
Neil Turton's avatar
Neil Turton committed
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
        MOV     R0,#ModHandReason_Free
        BL     XROS_Module
        Pull    "R0"
        B       doneblock
01
        Debug   ms,"Marking 'return to sender':",R2
        MOV     R14,#User_Message_Acknowledge   ; mark 'return to sender'
        STR     R14,[R2,#msb_reasoncode]
        LDR     R14,[R2,#msb_sender]            ; redirect back to sender
        STR     R14,[R2,#msb_receiver]

doneblock
        BICS    R14,R5,#msf_broadcast
        BNE     ExitPoll                ; R0, [userblk] set up
        B       repollwimp              ; may call returnmessage again


;;----------------------------------------------------------------------------
;; Send Message
;; Entry:  R0 = reason code to generate
;;         R1 --> message block
;;             R1+0 = size of block
;;             R1+4 = handle of sending task (filled in by Wimp)
;;             R1+8 = my ref field           (filled in by Wimp)
;;             R1+12 = your ref field (0 if none)
;;             R1+16 = message action
;;             R1+20 = message data (format depends on [R1+16]
;;         R2 = task / window handle (Wimp can tell them apart)
;;         R2 = 0 ==> broadcast
;;         R3 = icon handle (if R2 = window handle on entry)
;; Exit:   R2 = actual task handle (or 0 if R2=0 on entry)
;;         [R1+8] = reference number of message (if R0 was 17 or 18 on entry)
;;         if [R1+12] <> 0, then any message with that myref value is killed
;; Errors: no room in RMA for message block
;;         illegal task/window handle
;;         illegal reason code (R0 on entry to Wimp_SendMessage)
;;         illegal message block size (must be <= 256, and be a multiple of 4)
;;----------------------------------------------------------------------------

SWIWimp_SendMessage
232 233 234

        MyEntry "SendMessage"

Neil Turton's avatar
Neil Turton committed
235 236 237
; first find out if application is sending a font changed message
        Push    "R0-R1"
        LDR     R0,[R1,#16]
Kevin Bracey's avatar
Kevin Bracey committed
238
        LDR     R1,=Message_FontChanged
Neil Turton's avatar
Neil Turton committed
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
        CMP     R0,R1
        Pull    "R0-R1"
        BNE     ordinary_message
        TEQ     R0,#User_Message
        BNE     ordinary_message
        [ outlinefont
        BL      FindFont                ; this will broadcast the message if it succeedes
        ]
        BLVC    BPR_invalidatewholescreen
        B       ExitWimp
ordinary_message
        BL      int_sendmessage
        STR     R2,[sp,#1*4]            ; return R2 = actual task handle
        B       ExitWimp                ; (0 if error has occurred)


int_sendmessage_fromwimp
        Push    "LR"
        LDR     R14,taskhandle
        Push    "R14"
        MOV     R14,#0                  ; fake it so sender is task 0
        STR     R14,taskhandle
        BL      int_sendmessage
        Pull    "R14"
        STR     R14,taskhandle
        Pull    "PC"


Neil Turton's avatar
Neil Turton committed
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
; NK's optimise
; if there is already a message_slot_size on the message queue
; for this task, then just update it rather than add another.

      [ NKmessages2

check_mem_message
        TEQ     R0,#User_Message
        MOVNE   PC,LR

        Push    "R7,LR"
        LDR     R7,=Message_SlotSize
        LDR     LR,[R1,#16]
        TEQ     LR,R7
        Pull    "R7,PC",NE

; check queue
        Push    "R0-R3"
        LDR     R0,headpointer
        LDR     R2,taskhandle
        CMP     R2,#0
        LDRGT   R14,[wsptr,R2]          ; NB task must be alive!
        LDRGT   R14,[R14,#task_flagword]
        MOVGT   R14,R14,LSR #flag_versionbit
        ORRGT   R2,R2,R14,LSL #flag_versionbit
Ben Avison's avatar
Ben Avison committed
292 293
        CMP     R0,#nullptr
        LDRNE   R0,[R0,#msb_link]       ; skip first message on stack - it may already have been delivered to some tasks
Neil Turton's avatar
Neil Turton committed
294
05
Ben Avison's avatar
Ben Avison committed
295 296
        CMP     R0,#nullptr
        BEQ     %FT99
Neil Turton's avatar
Neil Turton committed
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
        LDR     R3,[R0,#msb_reasoncode]
        TEQ     R3,#User_Message
        LDREQ   R3,[R0,#msb_sender]
        TEQEQ   R3,R2
; its the same task, is it the right message?
        LDREQ   R3,[R0,#msb_size+16]
        TEQEQ   R3,R7
        LDRNE   R0,[R0,#msb_link]
        BNE     %BT05

        LDR     R2,[R1,#24]             ; new next slot
        LDR     R1,[R1,#20]             ; new current

        STR     R1,[R0,#msb_size+20]
        STR     R2,[R0,#msb_size+24]
        Pull    "R0-R3,R7,PC"

99
        CMP     PC,#0
        Pull    "R0-R3,R7,PC"
      ]


Neil Turton's avatar
Neil Turton committed
320 321 322 323 324 325 326
int_sendmessage
        Push    "R3-R7,handle,LR"
;
        Debuga  ms,"*"
;
; validate receiving task / window handle
;
Neil Turton's avatar
Neil Turton committed
327 328 329 330 331
      [ NKmessages2
        BL      check_mem_message
        Pull    "R3-R7,handle,PC",EQ
      ]

Neil Turton's avatar
Neil Turton committed
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 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
        MOV     R6,#msh_wastask         ; assume not a window handle first
;
        CMP     R2,#0                   ; 0 ==> broadcast to all tasks
        LDREQ   R2,=(:INDEX:taskpointers):OR:msf_broadcast
        BEQ     gottaskhandle
;
        TST     R2,#3
        BEQ     trytaskhandle
;
        CMP     R2,#nullptr2            ; is this the icon bar?
        MOVNE   R6,R2                   ; R6 = window handle
        BNE     %FT01
;
        Push    "R0,R1"
        ORR     R6,R3,#msh_iconbar      ; R6 = window/icon handle
        MOV     R4,R3                   ; R4 = icon handle
        BL      findicon                ; R7 --> iconbar left/right (ignored)
        Pull    "R0,R1"
        LDREQ   R2,[R2,#icb_taskhandle]
        MOVNE   R2,#0                   ; if not found, don't deliver
        B       %FT02                   ; else add in version bits
01
        MOVS    handle,R2               ; if R2<0, treat as system window
        MOVMI   R2,#0                   ; 0 => system, -1 => menu
        BLPL    checkhandle             ; preserves flags (unless error)
        Pull    "R3-R7,handle,PC",VS    ; illegal window handle
        LDRPL   R2,[handle,#w_taskhandle]
02

; see if this window belongs to the Wimp or the menu owner
; if version 2.18 or later, menu owners can receive messages for menus

        CMP     R2,#0                   ; get the Wimp to interpret some actions
        CMPLE   R0,#Close_Window_Request
        LDRLE   R2,=MSToWimpMagicHandle ; Special Wimp window task handle for message system
        BLE     gottaskhandle

        CMP     R2,#0                   ; if this is a Wimp window,
        BGT     %FT03
        LDRLT   R2,menutaskhandle       ; see if the menu owner is clever
        CMPLT   R2,#0
        MOVLT   R2,#0
        BLE     gottaskhandle           ; don't deliver if Wimp window or no menus

        LDR     R14,[wsptr,R2]
        TST     R14,#task_unused
        MOVNE   R14,#0
        LDREQ   R14,[R14,#task_wimpver] ; does it know about Wimp 2.18?
        CMP     R14,#218
        MOVLT   R2,#0
        BLT     gottaskhandle
03

; convert internal task handle to external form

        LDR     R14,[wsptr,R2]          ; add in version bits (if alive)
        TST     R14,#task_unused
        LDREQ   R14,[R14,#task_flagword]
        MOVEQ   R14,R14,LSR #flag_versionbit
        ORREQ   R2,R2,R14,LSL #flag_versionbit
        B       gottaskhandle

trytaskhandle
        BL      validtask               ; In: R2=task, Out: R5=internal task
        BVS     %FT99                   ; don't worry if it's dead yet

; work out sender for all types of message

gottaskhandle
        LDR     R4,taskhandle           ; set up sender and myref fields
        CMP     R4,#0
        LDRGT   R14,[wsptr,R4]          ; NB task must be alive!
        LDRGT   R14,[R14,#task_flagword]
        MOVGT   R14,R14,LSR #flag_versionbit
        ORRGT   R4,R4,R14,LSL #flag_versionbit
        STR     R4,sender               ; used later when block is copied
;
; now check for user message / other reason code
;
        Debug   ms,"SendMessage: R0,R1,R2,R6 (processed) =",R0,R1,R2,R6
        TEQ     R0,#User_Message
        TEQNE   R0,#User_Message_Recorded
        TEQNE   R0,#User_Message_Acknowledge
        BNE     notusermess
;
        Push    "R3-R7"
        LDMIA   R1,{R3-R7}
        Debug   ms,"UserMessage:",R3,R4,R5,R6,R7
        Pull    "R3-R7"
;
; delete queued message if referenced by 'yourref'
; (it is being acknowledged)
;
        LDR     R3,[R1,#ms_yourref]             ; NB: ms_ not msb_ !!!
        ADR     R4,headpointer-msb_link
01
        LDR     R5,[R4,#msb_link]
Ben Avison's avatar
Ben Avison committed
429 430
        CMP     R5,#nullptr
        BEQ     doneackmess                     ; finished
Neil Turton's avatar
Neil Turton committed
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
        LDR     R14,[R5,#msb_myref]
        TEQ     R14,R3                          ; same id?
        MOVNE   R4,R5
        BNE     %BT01

        [ true
        LDR     R14,[R5,#msb_reasoncode]                ; WAGA WAGA WAGA!!!!
        TEQ     R14,#User_Message
        TEQNE   R14,#User_Message_Recorded
        TEQNE   R14,#User_Message_Acknowledge
        MOVNE   R4,R5

        BNE     %BT01
        ]
;
        Debug   ms,"Acknowledged block deleted:",R5
        Push    "R0-R2"
        LDR     R14,[R5,#msb_link]              ; #nullptr in version 1.43 !!!
        STR     R14,[R4,#msb_link]
Neil Turton's avatar
Neil Turton committed
450
        CheckMsgQ
Neil Turton's avatar
Neil Turton committed
451 452 453 454 455 456 457 458 459 460 461 462 463 464
        MOV     R0,#ModHandReason_Free
        MOV     R2,R5
        BL     XROS_Module
        Pull    "R0-R2"                 ; ignore errors
doneackmess
;
; set up sender and myref fields automatically
; NB: sender taskhandle includes version number bits!
;
        LDR     R14,myref
        ADDS    R14,R14,#1              ; clears V too!
        ADDEQ   R14,R14,#1              ; avoid 0
        STR     R14,myref
;
Ben Avison's avatar
Ben Avison committed
465 466 467 468
        LDR     R3,ROMstart
        LDR     R5,ROMend
        CMP     R1,R3                   ; don't splat the ROM!
        CMPHS   R5,R1
469
        LDR     R4,sender               ; worked out earlier
Ben Avison's avatar
Ben Avison committed
470 471
        STRLO   R4,[R1,#ms_sender]
        STRLO   R14,[R1,#ms_myref]
Neil Turton's avatar
Neil Turton committed
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
        Debug   ms,"New sender,my_ref =",R4,R14
;
; check for User_Message_Acknowledge - if it is, then don't actually send it
; (the message has already done its job)
;
        TEQ     R0,#User_Message_Acknowledge
        BEQ     %FT99                   ; return R2 = actual task handle

notusermess
        BL      calcmessagesize         ; R0,R1 = reasoncode,block;
;                                       ; on exit R3 = size
        Push    "R0-R3"                 ; reasoncode,block,receiver,size
        ADDVC   R3,R3,#msb_size
        BLVC    claimblock              ; R2 --> allocated block
        ADDVS   sp,sp,#4*4
        BVS     %FT99
Neil Turton's avatar
Neil Turton committed
488 489 490 491 492

; use lastpointer to determine where we should put the message

      [ NKmessages1
        LDR     R4,lastpointer
Ben Avison's avatar
Ben Avison committed
493 494
        CMP     R4,#nullptr
        ADREQ   R4,headpointer-msb_link
Neil Turton's avatar
Neil Turton committed
495
      |
Neil Turton's avatar
Neil Turton committed
496 497 498
        ADR     R4,headpointer-msb_link
01
        LDR     R14,[R4,#msb_link]
Ben Avison's avatar
Ben Avison committed
499 500 501
        CMP     R14,#nullptr
        MOVNE   R4,R14
        BNE     %BT01
Neil Turton's avatar
Neil Turton committed
502 503
      ]

Neil Turton's avatar
Neil Turton committed
504 505
        STR     R2,[R4,#msb_link]       ; add to end of list (FIFO)
        STR     R6,[R2,#msb_handle]     ; hope this is still intact!
Neil Turton's avatar
Neil Turton committed
506 507 508 509
      [ NKmessages1
        STR     R2,lastpointer
      ]

Neil Turton's avatar
Neil Turton committed
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
        Pull    "R4-R7"
;
; R4=reasoncode, R5=block, R6=receiver, R7=size
;
        MOV     R0,#nullptr
        ASSERT  msb_link = 0
        ASSERT  msb_receiver = 4
        ASSERT  msb_allsender = 8
        LDR     R14,sender
        STMIA   R2,{R0,R6,R14}
;
        STR     R4,[R2,#msb_reasoncode] ; reason code
        ADD     R2,R2,#msb_size
        B       %FT03
01
        LDR     R14,[R5,R7]
        TEQ     R4,#User_Message        ; can't be User_Message_Acknowledge!
        TEQNE   R4,#User_Message_Recorded
        BNE     %FT02
        TEQ     R7,#ms_sender
        LDREQ   R14,sender              ; in case block was in ROM
        TEQ     R7,#ms_myref
        LDREQ   R14,myref               ; ditto
02
        STR     R14,[R2,R7]
03
        SUBS    R7,R7,#4                ; now the actual message block
Ben Avison's avatar
Ben Avison committed
537
        BPL     %BT01
Neil Turton's avatar
Neil Turton committed
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600
;
; message is not actually sent until the next Wimp_Poll
;
        MOVS    R2,R6                   ; on exit R2 = actual task handle
        MOVMI   R2,#0                   ; if broadcast, don't confuse punter
99
        MOVVS   R2,#0                   ; message not sent if error occurs
        Pull    "R3-R7,handle,PC"

        LTORG

; Get the Wimp to decide a message directly, if addressed at a system window
; In:   R2 -> msb message block
;       R5 = MSToWimpMagicHandle
; Out:  Goes to postposting (to junk message)
;       R2, R5 preserved

autowimp_menu
        LDR     R0,[R2,#msb_reasoncode]
        TEQ     R0,#Open_Window_Request
        BEQ     %FT01
        TEQ     R0,#Close_Window_Request
        BNE     postposting
        LDR     R0,[R2,#msb_size+u_handle]
        BL      int_close_window
        B       postposting
01
        Push    "R2,R5"
;
        LDR     R1,[R2,#msb_allsender]
        Debug   autoopen,"Open request came from task :",r1
        TEQ     r1,#0
        Pull    "R2,R5",NE
        BNE     postposting             ; refuse to open if not from WIMP.
;
        ADD     R1,R2,#msb_size
        MOV     userblk,R1
        Debug   opn,"Openning one of the wimp's windows..."
        BL      int_open_window
        Debug   opn,"Wimp window successfully opened"
        Pull    "R2,R5"
        B       postposting

;
; Entry:  R2 = external task handle
; Exit:   R5 = internal task handle, V clear (if valid)
;         R0 --> "Bad Task handle", V set (if invalid)
;         note that the version bits are not validated at this stage
;         preserves all but R5 if no error
;

validtask
        Push    "R3,LR"
;
        LDR     R5,=:INDEX:taskpointers
        MOV     R3,#maxtasks
        MOV     R14,R2,LSL #32-flag_versionbit
01
        TEQ     R14,R5,LSL #32-flag_versionbit
        Pull    "R3,PC",EQ              ; do this even if task is dead
        ADD     R5,R5,#4                ; (message is ignored later)
        SUBS    R3,R3,#1
        BNE     %BT01
Neil Turton's avatar
Neil Turton committed
601
        Debug   opn,"**** validtask fails handle",R2
Neil Turton's avatar
Neil Turton committed
602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624
        MyXError  WimpBadTaskHandle
        Pull    "R3,PC"
        MakeErrorBlock WimpBadTaskHandle
        LTORG

;
; Entry:  R2 = external task handle
; Exit:   R5 = internal task handle, V clear (if valid)
;         R6 --> task block (if alive)
;         R0 --> "Bad Task handle", V set (if invalid, or dead)
;

validtask_alive
        Push    "LR"
;
        BL      validtask
        Pull    "PC",VS
;
        LDR     R6,[wsptr,R5]          ; if this is not the same task
        TST     R6,#task_unused
        LDREQ   R14,[R6,#task_flagword]        ; (compare version numbers)
        MOVEQ   R14,R14,LSR #flag_versionbit
        TEQEQ   R14, R2,LSR #flag_versionbit
Neil Turton's avatar
Neil Turton committed
625 626 627 628
      [ debug
        Pull    "PC",EQ
        Debug   err,"**** validtask_alive fails handle",R2
      ]
Neil Turton's avatar
Neil Turton committed
629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 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
        MyXError  WimpBadTaskHandle,NE
        Pull    "PC"

;
; Entry:  R0 = reason code
;         R1 --> user block
;

calcmessagesize
        Push    "LR"
;
        CMP     R0,#max_reason
        BCS     err_badreason
        ADR     R14,mess_sizes
        LDR     R3,[R14,R0,LSL #2]
        CMP     R3,#0
        Pull    "PC",GE                 ; < 0 ==> work it out
;
        TEQ     R0,#Menu_Select
        BEQ     go_menuselsize
        TEQ     R0,#User_Message
        TEQNE   R0,#User_Message_Recorded
        TEQNE   R0,#User_Message_Acknowledge
        BNE     err_badreason
        LDR     R3,[R1,#ms_size]
        TST     R3,#3                   ; must be a multiple of 4
        BNE     err_badmesssize
        CMP     R3,#max_messsize
        RSBLSS  R14,R3,#min_messsize   ; must include header
        Pull    "PC",LS

err_badmesssize
        MyXError  WimpBadMessageSize
        Pull    "PC"

mess_sizes
        DCD     4 * 0                   ; null
        DCD     4 * 1                   ; redraw_window
        DCD     4 * 8                   ; open_window (wh,x0,y0,x1,y1,sx,sy,bh)
        DCD     4 * 1                   ; close_window
        DCD     4 * 1                   ; ptr_leaving_window
        DCD     4 * 1                   ; ptr_entering_window
        DCD     4 * 6                   ; mouse_click (mx,my,bt,wh,ih,ob)
        DCD     4 * 4                   ; user_dragbox (x0,y0,x1,y1)
        DCD     4 * 7                   ; key_pressed (wh,ih,x,y,h,i,k)
        DCD     -1                      ; menu_select
        DCD     4 * 10                  ; scroll_window (cf. open_window)
        DCD     4 * 6                   ; lose_caret
        DCD     4 * 6                   ; gain_caret
        DCD     0               ;
        DCD     0               ; reserved (13..16)
        DCD     0               ;
        DCD     0               ;
        DCD     -1                      ; user_message
        DCD     -1                      ; user_message_recorded
        DCD     -1                      ; user_message_acknowledge
        ASSERT  (.-mess_sizes) = max_reason*4

go_menuselsize
        MOV     R3,R1                   ; R3 --> start of block
01
        LDR     R14,[R3],#4
        CMP     R14,#0                  ; stop on -1
        BGE     %BT01
        SUB     R3,R3,R1                ; R3 = size of block
        Pull    "PC"

err_badreason
        MyXError  WimpBadReasonCode
        Pull    "PC"

        MakeErrorBlock WimpBadMessageSize
        MakeErrorBlock WimpBadReasonCode

;
; mark any queued messages relating to windows/icons if window/icon deleted
; Entry:  R0 = window/icon handle
;

msh_iconbar     *       1:SHL:30
msh_wastask     *       1:SHL:29

byemessages
        Push    "R1,LR"
;
        ADR     R1,headpointer-msb_link
01
        LDR     R1,[R1,#msb_link]
Ben Avison's avatar
Ben Avison committed
717 718
        CMP     R1,#nullptr
        Pull    "R1,PC",EQ
Neil Turton's avatar
Neil Turton committed
719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749
;
        LDR     R14,[R1,#msb_handle]
        TEQ     R14,R0
        MOVEQ   R14,#0
        STREQ   R14,[R1,#msb_receiver]  ; this won't now be delivered
        B       %BT01


;;----------------------------------------------------------------------------
;; Start task
;; Entry:  R0 --> command (passed to XOS_CLI)
;; Exit:   eventually the Wimp will get back to you !!!
;;----------------------------------------------------------------------------

SWIWimp_StartTask
        MyEntry "StartTask"
;
; you can only start a task if you are a live Wimp task yourself
;
        LDR     R5,taskhandle
        LDR     R6,singletaskhandle
        TEQ     R5,R6
        LDRNE   R4,[wsptr,R5]                   ; check that parent is alive
        TEQNE   R4,#task_unused                 ; note TEQ not TST !!!
        MyXError  WimpCantTask,EQ
;
; save FP registers on Wimp_StartTask if task knows about Wimp 2.23 onwards
;
        BLVC    saveFPregs                      ; R4 -> task block
        BVS     ExitWimp
;
750
; save VFP context, lazily if possible
751 752 753
;
        Push    "R0-R1"
        MOV     R0,#0
754
        MOV     R1,#VFPSupport_ChangeContext_Lazy+VFPSupport_ChangeContext_AppSpace
755 756 757 758 759
        SWI     XVFPSupport_ChangeContext
        MOVVS   R0,#0 ; Ignore error (probably means VFPSupport isn't loaded)
        STR     R0,[R4,#task_vfpcontext]
        Pull    "R0-R1"
;
Neil Turton's avatar
Neil Turton committed
760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777
; find a spare task handle for the new task
;
        ADRL    R5,taskpointers
        MOV     R6,#maxtasks
01
        LDR     R14,[R5],#4
        TST     R14,#task_unused
        BNE     %FT02
        SUBS    R6,R6,#1
        BNE     %BT01
;
        MyXError  WimpNoTasks
        B       ExitWimp
02
        SUB     R5,R5,#4                ; R5 --> task data pointer entry
;
; now stash the parent task on the return stack, and start up the new one
;
778
        ADRL    R1,taskbuffer
Neil Turton's avatar
Neil Turton committed
779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814
01
        LDRB    R14,[R0],#1
        STRB    R14,[R1],#1
        CMP     R14,#32                 ; terminate on any ctrl-char
        BCS     %BT01
;
        BL      mapslotout              ; map parent out of the way
;
        LDR     R14,taskSP
        LDR     handle,polltaskhandle
        STR     handle,[R14],#4         ; empty ascending stack
        STR     R14,taskSP
        SUB     R14,R5,wsptr
        STR     R14,taskhandle
;
; we must mark the task used, so that ExitPoll can swap into it
; Version number = 0 => task is not initialised
;
        MOV     R0,#0                   ; latest known Wimp version
        BL      markinitialised         ; changes task 'version number'
        BVS     ExitWimp
;
        LDR     R14,taskhandle          ; assume single-tasking for now
        STR     R14,singletaskhandle
;
        MOV     R14,#0                  ; reset all handlers
        STR     R14,handlerword
        STR     R14,parentquithandler   ; must start application !!!
        BL      setdefaulthandlers
;
; allocate memory for the new task, then use callback to start it up
; [taskbuffer..] contains the *command to execute
;
        ADRL    R14,Module_BaseAddr
        BL      allocateslot            ; updates memorylimit
;
815
        ADRL    R0,taskbuffer           ; copy of *command is in here
Neil Turton's avatar
Neil Turton committed
816 817 818
        LDR     R5,taskhandle
        LDR     R5,[wsptr,R5]
        ADRL    R14,runthetask          ; PC must be set up explicitly
Kevin Bracey's avatar
Kevin Bracey committed
819 820 821 822 823 824 825
        STR     R14,[R5,#task_registers+4*15]   ; note PC has no flags, ie USR on 26-bit
        ; this next bit is harmless on a 26-bit system, as the 17th word is ignored
        MRS     R14,CPSR
        BIC     R14,R14,#2_11101111     ; get USR26/USR32, ARM, FIQs+IRQs on
        STR     R14,[R5,#task_registers+4*16]


Neil Turton's avatar
Neil Turton committed
826 827 828 829 830 831 832
;
; to be on the safe side, bring up a text window if any chars printed
;
        Push    "R0"                    ; this allows escape etc.
        SWI     XWimp_CommandWindow     ; in case this is a wally task
        Pull    "R0"                    ; Remember *command ptr
        CLRV
833 834

        B       ExitPoll_tochild        ; swap tasks, and end up at 'runthetask'
Neil Turton's avatar
Neil Turton committed
835 836 837 838 839 840 841 842 843 844 845 846 847

        MakeErrorBlock WimpCantTask
        MakeErrorBlock WimpNoTasks

;
; Entry point where we run the task!
; Entry:  R0 --> command to execute
;         entered in USR mode (I hope!)
;

runthetask
        MOV     R1,R0                   ; close down the task !!!
        SWI     Wimp_CloseDown
848

Neil Turton's avatar
Neil Turton committed
849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000
        MOV     R0,R1
        SWI     OS_CLI                  ; R0 --> OS_CLI command
        SWI     OS_Exit                 ; exit back to Wimp

;
; set up default environment handlers (Wimp should replace them all)
; only reset the ones corresponding to 0 bits in [handlerword]
;  0 in table ==> leave alone (MemoryLimit,ApplicationSpaceSize)
;  1 in table ==> use default handler
; >1 in table ==> use values in table
;

setdefaulthandlers
        Push    "R1-R6,LR"
;
        ADR     R4,defaulthandlers      ; R4 --> data
        LDR     R5,handlerword          ; R5 = flag word (0 bit ==> set it)
        MOV     R6,#MaxEnvNumber
01
        LDR     R1,[R4],#4              ; if zero, it's not an address offset
        TEQ     R1,#0
        RSBEQ   R0,R6,#MaxEnvNumber     ; R1=0 ==> use default handler
        SWIEQ   XOS_ReadDefaultHandler  ; NB: R0 can be set to 0 by this call!
        Pull    "R1-R6,PC",VS
        ADDNE   R1,R1,R4                ; R1 --> code address
        MOVNE   R2,wsptr
        ADRNE   R3,errorbuffer
02
        MOVS    R5,R5,LSR #1            ; has this handler been set already?
        RSBCC   R0,R6,#MaxEnvNumber
        SWICC   XOS_ChangeEnvironment
        SUBS    R6,R6,#1
        BNE     %BT01
;
        Pull    "R1-R6,PC"

;
; Default settings to pass to SWI XOS_ChangeEnvironment
;       R1 --> code address / buffer pointer
;       R2  =  returned in R12 (if R1 is an address) - maybe
;       R3 --> block           (if R1 is an address)
;

defaulthandlers
        DCD     0                       ; MemoryLimit

        DCD     0                       ; UndefinedHandler
        DCD     0                       ; PrefetchAbortHandler
        DCD     0                       ; DataAbortHandler
        DCD     0                       ; AddressExceptionHandler
        DCD     0                       ; OtherExceptionHandler

        DCD     Do_ErrorHandler-.-4
        DCD     0                       ; CallBackHandler
        DCD     0                       ; BreakPointHandler

        DCD     0                       ; EscapeHandler
        DCD     0                       ; EventHandler
        DCD     Do_ExitHandler-.-4
        DCD     0                       ; UnusedSWIHandler

        DCD     0                       ; ExceptionDumpArea
        DCD     0                       ; ApplicationSpaceSize
        DCD     Module_BaseAddr-.-4     ; CAO pointer

        DCD     0                       ; upcall handler

        ASSERT  (.-defaulthandlers)/4 = MaxEnvNumber

;
; report error contained in errorhandlerbuffer
; in USR mode here!
;

Do_ErrorHandler
        MOV     R12,R0                  ; wsptr is in R0!
      [ debugtask1
        ADRL    R13,stackspace
        Debuga  task1,"Error reported to Wimp: "
        CLI     "HostVdu"
        ADRL    R0,errorbuffer+8        ; skip saved PC & error number
        SWI     XOS_Write0
        SWI     XOS_NewLine
        CLI     "TubeVdu"
      ]
        ADRL    R0,errorbuffer+4        ; skip saved PC
        MOV     R1,#erf_cancelbox:OR:erf_htcancel:OR:erf_dontwait
        MOV     R2,#nullptr                        ; no application
        SWI     XWimp_ReportError
        SWI     XOS_Exit                ; must abort task (no error handler)

;
; delete task and exit back to the Wimp
; NB we must be in USR mode !!!
; NB Wimp_CloseDown causes the command window to be closed too
;

Do_ExitHandler
      [ debugtask1
        ADRL    R13,stackspace          ; need some stack to call debug!
      ]
        SWI     XWimp_CloseDown         ; delete task (may restore handler)
01
        MOV     R0, #198                ; read EXEC file handle
        MOV     R1, #0
        MOV     R2, #&FF
        SWI     XOS_Byte
        TEQ     R1, #0                  ; was an EXEC file open?
        BEQ     %FT02

        MOV     R0,#OSArgs_EOFCheck     ; if end of file, ignore it!
        SWI     XOS_Args
        TEQ     R2,#0
        BNE     %FT02

        ADR     r0, CliDPrompt
        ADR     r1, errorbuffer
        MOV     r2, #?errorbuffer
        MOV     r3, #0
        MOV     r4, #3
        SWI     XOS_ReadVarVal
        MOVVC   r0,r1
        MOVVC   r1,r2
        ADRVS   r0, DefaultPrompt
        MOVVS   r1, #1
        SWI     OS_WriteN

        ADR     R0,errorbuffer
        MOV     R1,#?errorbuffer
        MOV     R2,#32
        MOV     R3,#&FF
        SWI     OS_ReadLine             ; provoke errors (handler is there)
        SWICC   OS_CLI                  ; should preserve flags
        BCC     %BT01

        MOV     R0,#126                 ; acknowledge escape
        SWI     OS_Byte
        ADR     R0,ErrorBlock_Escape
        MOV     R1,#0
        MOV     R2,#0                   ; global error
        SWI     MessageTrans_ErrorLookup
        SWI     OS_GenerateError        ; generate escape error
        MakeErrorBlock Escape

02
        Debug   task1,"Exitting back to Wimp"
        ADR     R1,errorbuffer          ; ensure R1 > &8000 !!!
        SWI     XWimp_Poll              ; if task returns, it must be the last
        Debug   task1,"Poll returns - Exitting from Wimp"
        SWI     OS_Exit

CliDPrompt      =       "CLI$Prompt", 0
1001 1002 1003
      [ debug
        ALIGN
      ]
Neil Turton's avatar
Neil Turton committed
1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027
DefaultPrompt   =       "*"
                ALIGN


;;-----------------------------------------------------------------------------
;; Exit point for task-switching
;;-----------------------------------------------------------------------------

; Report any errors during Wimp_Poll internally, unless single-tasking

reporterror
        LDR     R5,taskhandle
        LDR     R6,singletaskhandle
        TEQ     R5,R6
        BEQ     returnerror             ; can return errors to single task

        MOV     R1,#erf_okbox
        ADR     R2,wimp
        SWI     XWimp_ReportError
        B       repollwimp

wimp    DCB     "Wimp",0
        ALIGN

1028 1029 1030 1031 1032 1033
ExitPoll_tochild
        Debug   task1,"Exit to child:",#taskhandle
        MOV     R14,#-2
        STR     R14,sender              ; don't call postfilters
        B       ExitPoll

Neil Turton's avatar
Neil Turton committed
1034 1035 1036 1037 1038 1039
ExitPoll_toparent
        Debug   task1,"Exit to parent:",#taskhandle
        MOV     R14,#-1
        STR     R14,sender              ; don't return R2 from Wimp_StartTask

ExitPoll
1040
        Debug   poll2, "ExitPoll"
Neil Turton's avatar
Neil Turton committed
1041 1042 1043 1044 1045 1046 1047 1048
        BVS     reporterror             ; don't return to caller
returnerror

; The Wimp MUST NOT exit to a dead task (no register data !!!)
; Wimp_Poll tries to find a live task on entry - it calls OS_Exit if none left

        LDR     handle,taskhandle
;
1049 1050
        LDR     R14,ptr_DomainId
        STR     handle,[R14]            ; for Stuart
Neil Turton's avatar
Neil Turton committed
1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070

        Debug   task,"Exit Poll: (old),task,reason =",#polltaskhandle,handle,R0

        TEQ     R0,#No_Reason           ; Not a null event?
 [ Stork
  [ PokeBorder
        Push    "R0-R1",NE
        LDRNE   R1, =&40FFFF00          ; cyan = fast
        MOVNE   R0, #VIDC
        STRNE   R1, [R0]
        Pull    "R0-R1",NE
  ]
        LDRNE   R14, WimpPortableFlags
        BICNE   R14, R14, #PowerSave
        STRNE   R14, WimpPortableFlags  ; (so go at full speed)
        TSTNE   R14, #PortableFeature_Speed     ; And speed switching works?
 |
        LDRNE   R14,WimpPortableFlag
        TEQNE   R14,#0                  ; And the portable module present?
 ]
Ben Avison's avatar
Ben Avison committed
1071 1072 1073 1074 1075 1076 1077
        BEQ     %FT01
        Push    "R0-R1"
        MOV     R0,#0
        MOV     R1,#0
        SWI     XPortable_Speed         ; if not a null event then make it go fast
        Pull    "R0-R1"
01
Neil Turton's avatar
Neil Turton committed
1078 1079 1080 1081 1082 1083 1084 1085 1086
      [ debugtask3
        LDR     R14,singletaskhandle
        CMP     R14,#nullptr            ; if single-tasking,
        CMPNE   R14,handle              ; we mustn't exit to anyone else!!!
        BEQ     %FT01
        Debug   task3,"Task swap: single,taskhandle =",R14,handle
01
      ]

1087
        Push    "R0-R1"
Neil Turton's avatar
Neil Turton committed
1088 1089 1090
        LDR     R4,[wsptr,handle]
        TEQ     R4,#task_unused

Kevin Bracey's avatar
Kevin Bracey committed
1091 1092 1093
      [ debugtask4
; Stamp with event time for task priority and swapping

Neil Turton's avatar
Neil Turton committed
1094 1095 1096 1097 1098
        SWINE   XOS_ReadMonotonicTime
        BEQ     %FT00
        Debug   task4,"Time",R0
00
        STRNE   R0,[R4,#task_eventtime]
Kevin Bracey's avatar
Kevin Bracey committed
1099
      ]
Neil Turton's avatar
Neil Turton committed
1100 1101 1102

; restore FP registers if they were saved (ie. save block present)

1103 1104
        LDRNE   R0,[R4,#task_fpblock]
        TEQNE   R0,#0                   ; NE => restore registers
Neil Turton's avatar
Neil Turton committed
1105 1106 1107 1108
        MOVEQ   R5,#C_runtime_status    ; ensure caller gets &70000 if he didn't save regs
        WFSEQ   R5
        BEQ     %FT01

1109
        Debug   fp,"Restoring FP state from block at",R0
Neil Turton's avatar
Neil Turton committed
1110 1111 1112

        MOV     R5,#0                   ; avoid FP exceptions
        WFS     R5                      ; will still occur if FPEmulator RMKilled
Kevin Bracey's avatar
Kevin Bracey committed
1113
      [ FPE4
1114
       [ false
1115 1116
        LFM     F0,4,[R0,#fp_reg0]      ; (only gets here if active previously)
        LFM     F4,4,[R0,#fp_reg4]
1117 1118 1119
       |
        ; AAsm assembles the above as post-indexed not pre-indexed.
        ; Do it manually (bluch).
1120 1121
        DCD     &ED900200 :OR: (fp_reg0:SHR:2)
        DCD     &ED904200 :OR: (fp_reg4:SHR:2)
1122
       ]
Kevin Bracey's avatar
Kevin Bracey committed
1123
      |
1124 1125 1126 1127 1128 1129 1130 1131
        LDFE    F0,[R0,#fp_reg0]        ; (only gets here if active previously)
        LDFE    F1,[R0,#fp_reg1]
        LDFE    F2,[R0,#fp_reg2]
        LDFE    F3,[R0,#fp_reg3]
        LDFE    F4,[R0,#fp_reg4]
        LDFE    F5,[R0,#fp_reg5]
        LDFE    F6,[R0,#fp_reg6]
        LDFE    F7,[R0,#fp_reg7]
Kevin Bracey's avatar
Kevin Bracey committed
1132
      ]
1133
        LDR     R5,[R0,#fp_status]
Neil Turton's avatar
Neil Turton committed
1134 1135
        WFS     R5
01
1136 1137 1138 1139 1140 1141 1142
; restore VFP context
        TEQ     R4,#task_unused
        LDRNE   R0,[R4,#task_vfpcontext]
        MOVNE   R1,#VFPSupport_ChangeContext_Lazy
        TEQNE   R0,#0 ; We should already be on the null context, so only call if user does have a context to restore
        SWINE   XVFPSupport_ChangeContext
        Pull    "R0-R1"
Neil Turton's avatar
Neil Turton committed
1143
;
1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176
      [ StartTaskPostFilter
        LDR     R14,sender
        CMP     R14,#-1
        BLT     %FT01                ; Are we starting up Wimp_StartTask?
        BNE     %FT02                ; Are we returning from Wimp_StartTask?

; We're returning from Wimp_StartTask and
; R0 = task handle of child (or 0). Wimps before 3.96
; would not call the post-filter in this case, but would
; call it if Wimp_StartTask returned 0 (so the filter
; would think a null event was happening.) Now, the
; Toolbox (and probably other filters) relies on the
; post filter to monitor the current task. If the postfilter
; doesn't get called here then there is no way of telling
; that this task has become active. So, we now call the filter
; with a null event, and ignore any attempt to claim it. (In
; the past the filter was able to claim the "null" event if
; Wimp_StartTask returned 0, causing instant death.
; This is the problem that hit Toolbox 1.33).
;
; Hopefully this shouldn't cause any problems, as filters
; will have had to be able to deal with the dummy "null"
; event for at least some Wimp_StartTask calls already.

        Push    "R0,R1"
        MOV     R0,#No_Reason
        MOV     R1,userblk
        CallFilter postfilter           ; call the post-poll filter (ignoring
        Pull    "R0,R1"                 ; R0 return)
        B       %FT01

02
      |
Neil Turton's avatar
Neil Turton committed
1177 1178
        CMP     R0,#max_reason          ; Valid message?
        BHS     %FT01                   ; No then jump,maybe -> *command from Wimp_StartTask
1179
      ]
Neil Turton's avatar
Neil Turton committed
1180

Kevin Bracey's avatar
Kevin Bracey committed
1181
        Push    "R1"
Neil Turton's avatar
Neil Turton committed
1182 1183
        MOV     R1,userblk
        CallFilter postfilter           ; call the post-poll filter
Kevin Bracey's avatar
Kevin Bracey committed
1184
        Pull    "R1"
Neil Turton's avatar
Neil Turton committed
1185 1186 1187
        CMP     R0,#-1
        BEQ     repollwimp              ; if it claimed then just re-poll
01
1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210
      [ AutoHourglass
        Push    "R0-R2"
        LDR     R1, hourglass_status
      [ debugautohg
        Push    "handle"
        LDR     handle, taskhandle
        Debug   autohg, "Hourglass_On  at task switch: taskhandle, old status =", handle, R1
        Pull    "handle"
      ]
        TEQ     R1, #2
        SWIEQ   XHourglass_Off          ; if autohourglass is still pending or animating, turn it off
        TEQ     R1, #0
        MOVEQ   R0, #WrchV              ; get back on WrchV if necessary
        ADREQ   R1, deactivate_hourglass_on_wrchv
        BLEQ    claim

        MOV     R0, #hourglass_delay
        SWI     XHourglass_Start        ; turn on using special delay time
        CLRV                            ; ignore errors
        MOV     R1, #2
        STR     R1, hourglass_status    ; mark autohourglass fully active
        Pull    "R0-R2"
      ]
Neil Turton's avatar
Neil Turton committed
1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221
        BL      DeletePollTask          ; Delete task from polltask list

; don't need to do callback if this is the same task

        LDR     R14,polltaskhandle      ; see if this is the same task
        TEQ     handle,R14              ; NB doesn't affect V flag!!!
        BEQ     putsender_ExitWimp      ; exit, and set up R2 if required
;
; ensure that R0 and the flags are passed back to the correct task
; bodge: if same task, also keep R0 and flags now
;
Kevin Bracey's avatar
Kevin Bracey committed
1222
      [ No32bitCode
Neil Turton's avatar
Neil Turton committed
1223 1224
        Push    "R0,PC"                 ; save R0 and flags
        SETPSR  I_bit, R5               ; disable interrupts
Kevin Bracey's avatar
Kevin Bracey committed
1225 1226 1227 1228 1229 1230
      |
        MRS     R5,CPSR
        Push    "R0,R5"
        ORR     R5,R5,#I32_bit
        MSR     CPSR_c,R5
      ]
Neil Turton's avatar
Neil Turton committed
1231 1232 1233
;                                       ; NB preserve R14 in this code
        LDR     R5,[wsptr,handle]
        STR     R0,[R5,#task_registers+4*0]
Kevin Bracey's avatar
Kevin Bracey committed
1234
      [ No32bitCode
Neil Turton's avatar
Neil Turton committed
1235
        LDR     R0,[R5,#task_registers+4*15]
Kevin Bracey's avatar
Kevin Bracey committed
1236
      |
Ben Avison's avatar
Ben Avison committed
1237 1238 1239
        TEQ     PC,PC                           ; 32-bit system?
        LDRNE   R0,[R5,#task_registers+4*15]    ; 26-bit: modify R15
        LDREQ   R0,[R5,#task_registers+4*16]    ; 32-bit: modify CPSR
Kevin Bracey's avatar
Kevin Bracey committed
1240
      ]
Neil Turton's avatar
Neil Turton committed
1241 1242
        BICVC   R0,R0,#V_bit            ; set up correct V bit
        ORRVS   R0,R0,#V_bit
Kevin Bracey's avatar
Kevin Bracey committed
1243
      [ No32bitCode
Neil Turton's avatar
Neil Turton committed
1244
        STR     R0,[R5,#task_registers+4*15]   ; save for new task
Kevin Bracey's avatar
Kevin Bracey committed
1245
      |
Ben Avison's avatar
Ben Avison committed
1246 1247
        STRNE   R0,[R5,#task_registers+4*15]
        STREQ   R0,[R5,#task_registers+4*16]
Kevin Bracey's avatar
Kevin Bracey committed
1248
      ]
Neil Turton's avatar
Neil Turton committed
1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272
;
; set up callback handler
; NOTE: since the task is already paged in, its handlers are set up already
; XXXX: it appears that the handlers are not always in the block yet!
;
        Debug   task1,"Setting callback handler"
;
        MOV     R0,#CallBackHandler     ; be careful when old task is dead
        ADR     R1,callbackpoll
        MOV     R2,wsptr
        LDR     R3,[wsptr,R14]          ; save old task registers
        TST     R3,#task_unused
        ADDEQ   R3,R3,#task_registers   ; be careful of dead tasks!
        ADRNEL  R3,registerbuffer       ; use temporary buffer (regs ignored)
        SWI     XOS_ChangeEnvironment
        ADR     R14,oldcallback
        STMIA   R14,{R1-R3}             ; will be restored later
;
; Exit temporarily - comes back to callback handler
; NB -- SWI XWimp_Poll must be used, since I don't know about bit 17
;
        SWI     XOS_SetCallBack         ; set call back flag
;
        Pull    "R0,R14"
Kevin Bracey's avatar
Kevin Bracey committed
1273
      [ No32bitCode
Neil Turton's avatar
Neil Turton committed
1274
        TEQP    R14,#0                  ; restore flags, ready for exit
Kevin Bracey's avatar
Kevin Bracey committed
1275 1276 1277
      |
        MSR     CPSR_cf,R14             ; restore flags+ints, ready for exit
      ]
Neil Turton's avatar
Neil Turton committed
1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291
;
        B       ExitWimp_noswitch       ; pulls registers & exits to callback

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

; here R12 --> workspace (set up by ChangeEnvironment)
;
; Should enter this code in SVC mode with Ints off
; restore environment for new task

callbackpoll
      [ debugtask
        Push    "R0,LR"
;
Ben Avison's avatar
Ben Avison committed
1292
      [ No32bitCode
Neil Turton's avatar
Neil Turton committed
1293 1294 1295
        Push    "PC"
        Pull    "R0"
        AND     R0,R0,#ARM_CC_Mask
Ben Avison's avatar
Ben Avison committed
1296 1297 1298
      |
        MRS     R0, CPSR
      ]
Neil Turton's avatar
Neil Turton committed
1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315
        Debug   task,"Flags on entry to callbackpoll:",R0
;
        Pull    "R0,LR"
      ]
;
        LDR     R14,taskhandle
        LDR     R4,[wsptr,R14]          ; NB task cannot be dead
        BL      getsender_R2                    ; if [R4,#task_wimpver] >= 253
        STRGE   R2,[R4,#task_registers+2*4]     ; return R2 = sender's handle

        ADR     R0,oldcallback
        LDMIA   R0,{R1-R3}
        MOV     R0,#CallBackHandler
        SWI     XOS_ChangeEnvironment   ; restore client's handler!
;
; exit to caller
;
Ben Avison's avatar
Ben Avison committed
1316
        TEQ     PC,PC                           ; are we 26 or 32-bit?
Neil Turton's avatar
Neil Turton committed
1317
        ADD     lr_svc,R4,#task_registers       ; lr_svc --> register block
Ben Avison's avatar
Ben Avison committed
1318 1319
        LDREQ   R0,[lr_svc,#16*4]
        MSREQ   SPSR_cxsf,R0
Neil Turton's avatar
Neil Turton committed
1320 1321 1322 1323 1324
        LDMIA   lr_svc,{R0-R14}^                ; restore USR regs
        NOP
        LDR     lr_svc,[lr_svc,#15*4]
        MOVS    PC,lr_svc                       ; exit to caller, restoring flags

1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339
;..............................................................................

; WrchV routine to deactivate the autohourglass as soon as a character is output.
; The argument for this is that if the task is plotting something, you probably
; don't need the Wimp putting up an hourglass to let you know that the machine
; hasn't stiffed.
; Using this approach, the hourglass isn't shown, for example, while Paint is
; doing a screen grab (it doesn't Wimp_Poll, but it does plot a box on the screen).
; It also copes transparently with command windows, ShellCLI etc.

; On entry:  R12 -> workspace
;            [hourglass_status] = 1 or 2 (by definition)
;            processor is in SVC mode

      [ AutoHourglass
1340
deactivate_hourglass_on_wrchv Entry "R0-R2"
1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352
        LDR     R1, hourglass_status
        Debug   autohg, "Hourglass_Off at WrchV, old status =", R1
        TEQ     R1, #2
        SWIEQ   XHourglass_Off          ; turn off hourglass if necessary
        MOV     R0, #WrchV
        ADR     R1, deactivate_hourglass_on_wrchv
        BL      release                 ; release WrchV
        MOV     R1, #0
        STR     R1, hourglass_status    ; mark fully deactivated
        EXITS                           ; pass on call (NB: nowhere to return errors to)
      ]

Neil Turton's avatar
Neil Turton committed
1353 1354 1355 1356 1357 1358
;.............................................................................

; In    R4 -> task block of current task
; Out   FP registers saved if FPEmulator present and task knows Wimp 2.23

saveFPregs
Kevin Bracey's avatar
Kevin Bracey committed
1359
        EntryS  "R0-R3"
Neil Turton's avatar
Neil Turton committed
1360 1361 1362 1363 1364 1365 1366 1367 1368 1369

        Debug   fp,"Saving FP state for task",#taskhandle
        Debuga  fp,"Reading FP status: "

        RFS     R1                      ; <==== NB: pending trap can occur here
                                        ; so do it before claiming block!
        Debug   fp," value =",R1

        LDR     R2,[R4,#task_fpblock]           ; block may already be claimed
        CMP     R2,#0                           ; (assume will be required again)
Ben Avison's avatar
Ben Avison committed
1370 1371
        MOVEQ   R3,#fp_size
        BLEQ    claimblock                      ; R2 -> block address
Kevin Bracey's avatar
Kevin Bracey committed
1372 1373
        STRVS   R0,[sp,#Proc_RegOffset]
        EXIT    VS
Neil Turton's avatar
Neil Turton committed
1374 1375 1376 1377 1378 1379 1380
        STR     R2,[R4,#task_fpblock]

        Debug   fp,"FP save block at",R2

        STR     R1,[R2,#fp_status]
        LDR     R1,=C_runtime_status            ; now C run-time status value
        WFS     R1
Kevin Bracey's avatar
Kevin Bracey committed
1381
      [ FPE4
1382 1383 1384 1385 1386 1387 1388 1389 1390
       [ false
        SFM     F0,4,[R2,#fp_reg0]
        SFM     F4,4,[R2,#fp_reg4]
       |
        ; AAsm assembles the above as post-indexed not pre-indexed.
        ; Do it manually (bluch).
        DCD     &ED820200 :OR: (fp_reg0:SHR:2)
        DCD     &ED824200 :OR: (fp_reg4:SHR:2)
       ]
Kevin Bracey's avatar
Kevin Bracey committed
1391
      |
Neil Turton's avatar
Neil Turton committed
1392 1393 1394 1395 1396 1397 1398 1399
        STFE    F0,[R2,#fp_reg0]
        STFE    F1,[R2,#fp_reg1]
        STFE    F2,[R2,#fp_reg2]
        STFE    F3,[R2,#fp_reg3]
        STFE    F4,[R2,#fp_reg4]
        STFE    F5,[R2,#fp_reg5]
        STFE    F6,[R2,#fp_reg6]
        STFE    F7,[R2,#fp_reg7]
Kevin Bracey's avatar
Kevin Bracey committed
1400
      ]
Neil Turton's avatar
Neil Turton committed
1401
;
Kevin Bracey's avatar
Kevin Bracey committed
1402
        EXITS                                   ; preserve flags
Neil Turton's avatar
Neil Turton committed
1403 1404 1405 1406 1407 1408 1409 1410 1411

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

; In    handle = task handle of current task (must be alive)
;       R12 -> module workspace
;       [sp..] = stacked R1..
; Out   exits to Wimp with or without R2 set up (as appropriate)

putsender_ExitWimp
Kevin Bracey's avatar
Kevin Bracey committed
1412
        SavePSR R3                      ; save flags
Neil Turton's avatar
Neil Turton committed
1413 1414 1415
        LDR     R4,[wsptr,handle]
        BL      getsender_R2            ; GE => R2 = task handle of sender
        STRGE   R2,[sp,#4]              ; R2 = second word on stack
Kevin Bracey's avatar
Kevin Bracey committed
1416
        RestPSR R3,,f                   ; restore error state
Neil Turton's avatar
Neil Turton committed
1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429
        B       ExitWimp

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

; In    R4 -> task block for task about to receive an event
;       R12 -> module workspace
; Out   GE => R2 = task handle of task that sent it (0 => Wimp)

getsender_R2
        LDR     R2,[R4,#task_wimpver]   ; latest known Wimp version number
        Debug   ms,"getsender_R2: handle, wimpver, sender =",#taskhandle,R4,R2,#sender
        CMP     R2,#253
        LDRGE   R2,sender               ; GE => R2 = sender's task handle
1430
        CMPGE   R2,#0                   ; -1/-2 => this is a Wimp_StartTask
Neil Turton's avatar
Neil Turton committed
1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464
        MOV     PC,LR


;;----------------------------------------------------------------------------
;; Error reporting SWI
;;----------------------------------------------------------------------------
;
; Entry:  R1 --> icon definition
;         R2 = coords to centre on (horizontally)
; Exit:   x0,x1 = left,right of icon
;         icon definition updated
;

setbuttonx
        LDR     x0,[R1,#i_bbx0]
        LDR     x1,[R1,#i_bbx1]
        SUB     x1,x1,x0
        SUB     x0,R2,x1,ASR #1
        ADD     x1,x0,x1
        STR     x0,[R1,#i_bbx0]
        STR     x1,[R1,#i_bbx1]
        MOV     PC,LR                   ; must preserve flags

;
; Entry:  R0 --> error block
;         R1 = flags
;              bit 0 ==> OK box displayed
;              bit 1 ==> Cancel box displayed
;              bit 2 ==> highlight Cancel box (else highlight OK box)
;              bit 3 ==> dont wait for confirmation (if text-based)
;              bit 4 ==> omit 'Error from ' in title bar
;              bit 5 ==> 'poll' error window (ie. leave open & exit)
;              bit 6 ==> finish polling error window, select [r1] and close it
;              bit 7 ==> don't beep (even if WimpFlags bit 4 clear)
Kevin Bracey's avatar
Kevin Bracey committed
1465 1466 1467
;              bit 8 ==> new type error report
;              bits 9-11 ==> error type
;
Neil Turton's avatar
Neil Turton committed
1468
;         R2 --> application name (<=0 ==> Wimp has detected the error)
Kevin Bracey's avatar
Kevin Bracey committed
1469 1470
;         R3 --> sprite name (for new type error report)
;         R4 --> sprite area, or 1 for Wimp area (for new type error report)
1471 1472 1473
;         R5 --> comma separated additional button list, or 0 for none (for new type error report)
;
; Exit:   R1 = 1 ==> Continue (OK) box was selected
Neil Turton's avatar
Neil Turton committed
1474
;         R1 = 2 ==> Cancel box was selected
Kevin Bracey's avatar
Kevin Bracey committed
1475
;         R1 = 3,4... ==> additional button pressed
Neil Turton's avatar
Neil Turton committed
1476 1477
;

Kevin Bracey's avatar
Kevin Bracey committed
1478
;Rough outline (not gospel!) JRC 24 Jul 1997
1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513
;	Make service call ErrorStarting
;	IF	in command mode
;	THEN	report error in text
;		poll for a key press
;		return key pressed (Return/Escape)
;	ELSE	IF	closing an open error box
;		THEN	return button-click specified
;		ELSE	Create a window structure
;			Make service call WimpReportError 1
;			Switch output to screen
;			Disable file redirection
;			Enable VDU, disable Spool, printer & serial
;			Beep
;			Add the icon definitions to the window structure
;			int_open_window
;			int_redraw_window
;			int_get_rectangle
;			Smash hourglass
;			Bound pointer to window
;			Flush keyboard and mouse
;			Start IconHigh
;			DO	Read key with no time limit
;				Check mousebuttons
;			WHILE	nothing happens
;			Unbound pointer
;			int_close_window
;			Stop IconHigh
;			Make service call ErrorButtonPressed
;			Make service call ErrorEnding
;			Restore file redirection
;			Restore output to previous state
;			Make service call WimpReportError
;		FI
;	FI

Neil Turton's avatar
Neil Turton committed
1514 1515 1516 1517 1518 1519 1520
errorprefix     DCB     "NoError",0
errorprefix1    DCB     "Error",0
errorprefix2    DCB     "ErrorF",0

execcom DCB     "Exec",0
        ALIGN

1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531
; tempworkspace layout
                        ^       0
errtws_spritearea       #       4  ;   +0  as passed in R4 / set by service call claimant(s)
errtws_buttonlist       #       4  ;   +4  pointer to comma-separated list of buttons
errtws_iconend          #       4  ;   +8  icon handle of (rightmost == first-in-string == highest-icon-handle) extra button, + 1
errtws_describebuttons  #       4  ;  +12  comma-separated list of buttons to use when program error is Described
errtws_icondata         #       4  ;  +16  if a "may have gone wrong" window, -> start of icon data for error window, else 0
errtws_cancelstr        #       4  ;  +20  -> "Cancel"
errtws_flags            #       4  ;  +24
errtws_mustntuse        #       4  ;  +28  corrupted by text plotting code

Neil Turton's avatar
Neil Turton committed
1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547
SWIWimp_ReportError
        MyEntry "ReportError"
;
        [ ErrorServiceCall
        Push    "R0-R5"
        Pull    "R2-R7"
        LDR     R1,=Service_ErrorStarting
        SWI     XOS_ServiceCall
        Push    "R2-R7"
        Pull    "R0-R5"
        MOV     userblk,R1
        ]

        Push    "R0-R3"
;
        [ NewErrorSystem
1548 1549 1550
        STR     R4,tempworkspace+errtws_spritearea  ; R4 gets horribly corrupted
                                                    ; but is required for 3.21
        STR     R5,tempworkspace+errtws_buttonlist  ; ditto!
Neil Turton's avatar
Neil Turton committed
1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644
        ]

        LDR     R4,commandflag
        ORR     R14,R4,#cf_suspended
        STR     R14,commandflag         ; suspend this whatever
        TEQ     R14,#cf_active:OR:cf_suspended
        BNE     useerrorwindow

noerrorwindow                           ; come back here if error window dead
        TST     R1,#erf_dontwait
        ADREQ   R0,execcom              ; cancel exec file (if any)
        SWIEQ   XOS_CLI
;
        Pull    "R0-R3"
;
; report error as a line of text
;
        TST     R1,#erf_pollexit        ; finish - cancel suspended state
        ANDNE   R1,R1,#erf_okbox:OR:erf_cancelbox
        BNE     ExitError
;
        TST     R4,#cf_suspended        ; if suspended and poll bit set,
        TSTNE   R1,#erf_poll
        BNE     %FT11                   ; don't re-print the error message
;
        SWI     XOS_WriteI+4            ; just in case
        SWI     XOS_NewLine             ; textual form of error report
        ADD     R0,R0,#4
        SWI     XOS_Write0
        SWI     XOS_NewLine
;
        TST     R1,#erf_dontwait        ; R1 preserved if bit 3 was set
        BNE     ExitError
;
        TST     R1,#erf_poll            ; unless polling,
        BNE     %FT51

        Push    "R2,R3"
;
        ADRL    R0,pressspace
        ADRL    R2,errorbuffer
        MOV     R3,#?errorbuffer
        BL      LookupToken1            ; resolve the press-space to continue token
;
        ADRL    R0,errorbuffer
        SWI     XOS_Write0              ; display it
        SWI     XOS_NewLine             ; followed by a new line
;
        Pull    "R2,R3"
51
        BL      flushkbdmouse           ; only done the first time
11
        BL      pollforkey
        BNE     %FT12

        LDR     R1,[sp,#0*4]
        TST     R1,#erf_poll            ; if no result, loop unless erf_poll
        BEQ     %BT11
;
        MOV     R1,#0                   ; leave command window suspended
        B       ExitError2              ; return 'no result'

12      TEQ     R1,#&1B                 ; escape key ==> non-default

        Debug   err,"ReportError: key=",R1

        MOVNE   R1,#erf_okbox
        MOVEQ   R1,#erf_cancelbox
        LDR     R14,[sp,#0*4]
        TST     R14,#erf_htcancel
        EORNE   R1,R1,#erf_okbox:EOR:erf_cancelbox
        ANDS    R14,R14,#erf_okbox:OR:erf_cancelbox
        MOVEQS  R14,#erf_okbox          ; if flags =0 it has an OK box
        ANDS    R1,R1,R14               ; can't select button that wasn't there
        TSTEQ   R14,#erf_poll
        BEQ     %BT11                   ; try again if 0 not allowed!

        Debug   err,"ReportError: return",R1

ExitError
        LDR     R14,commandflag
        BIC     R14,R14,#cf_suspended
        STR     R14,commandflag

ExitError2
        STR     R1,[sp,#0*4]
        B       ExitWimp

;
; report error in a window
;

useerrorwindow
        LDR     R8,errorhandle          ; R8 = relative error window handle
Ben Avison's avatar
Ben Avison committed
1645 1646
        CMP     R8,#nullptr
        BEQ     noerrorwindow           ; oops!
Neil Turton's avatar
Neil Turton committed
1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669
;
        ADRL    R0,execcom              ; always cancel exec file (if any)
        SWI     XOS_CLI
;
        Abs     handle,R8               ; handle --> window definition
;
        TST     R1,#erf_pollexit
        BEQ     %FT01

        ADD     sp,sp,#4*4              ; skip junk on stack

        TST     R4,#cf_suspended        ; is error window open?
        BEQ     ExitError               ; forget it if not (unsuspend window)

        MOV     R4,#1                   ; highlight either icon 1 or 4
        TST     R1,#erf_okbox           ; ('OK' preferably)
        MOVEQ   R4,#4
        B       finisherror             ; make selection and close error window
01
        TST     R4,#cf_suspended        ; if suspended and poll bit set,
        TSTNE   R1,#erf_poll
        Pull    "R4-R7"                 ; R4-R7 = original R0-R3
        BLEQ    starterrorbox
1670

1671
        MOV     R0, #229                ; Read current escape condition enable state so we can restore it later
1672 1673 1674 1675 1676
        MOV     R1, #0
        MOV     R2, #255
        SWI     XOS_Byte
        STRB    r1, old_escape

1677 1678
        MOV     R0, #229                ; Disable escape conditions (Wimp hasn't actually checked for them for a long time)
        MOV     R1, #1
1679 1680
        MOV     R2, #0
        SWI     XOS_Byte
Neil Turton's avatar
Neil Turton committed
1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699
;
; bodge polling loop - look for mouse click in OK / Cancel boxes
;                    - also <escape> (27, or escape condition)
;

pollit
        MOV     R0,#&81                 ; read key with 0 time limit
        MOV     R1,#0
        MOV     R2,#0
        SWI     XOS_Byte                ; CS => escape, else R1 = &FF => no char
        TEQ     R2,#&FF
        BEQ     %FT02                   ; no key pressed
;
        Debug   err,"ReportError: pollit key=",R1

        TEQ     R1,#&0D
        TEQNE   R1,#&1B                 ; old allow <CR> and <Esc>
        BNE     %FT02
;
1700 1701 1702
        LDR     R14, tempworkspace+errtws_flags  ; to work out which button the key corresponds to, we need the current flags
                                                 ; note 1: these flags will be correct for "may have gone wrong" boxes
        Debug