4 REM TearoffSupport code (encrypted)
6 REM © 1994-1998 Straylight
9 REM ----- Licensing note ----------------------------------------------------
11 REM This file is part of Straylight's Tearoff Menu System (TMS), but it's
12 REM distributed with Straylight's core libraries (corelib).
14 REM TMS is free software; you can redistribute it and/or modify
15 REM it under the terms of the GNU General Public License as published by
16 REM the Free Software Foundation; either version 2, or (at your option)
19 REM TMS is distributed in the hope that it will be useful,
20 REM but WITHOUT ANY WARRANTY; without even the implied warranty of
21 REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 REM GNU General Public License for more details.
24 REM You should have received a copy of the GNU General Public License
25 REM along with Corelib. If not, write to the Free Software Foundation,
26 REM 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 ON ERROR ERROR 0,REPORT$+" ["+STR$(ERL)+"]"
32 PROCbas_aofInit(&4000)
34 XOS_ClaimProcessorVector=&20069
35 XOS_SynchroniseCodeAreas=&2006E
37 PRINT "Assembling...";
45 ;----- TearoffSupport interface code ----------------------------------------
47 FNarea("Asm$$Code","CODE,READONLY")
49 ; --- tearSupport_init ---
55 ; Use; Initialises tearSupport
57 FNexport("tearSupport_init")
60 stmfd r13!,{r0-r4,r12,r14} ;Save some registers
61 mvn r0,#0 ;Find address of TearSupport
62 swi "XOS_ChangeEnvironment" ;Find the address then
63 bvc tSupt_init10 ;If resident, skip install
65 ; --- We need to set up the RMA block ---
67 .tSupt_init00 ldr r3,ts__image ;Load RMA block size wanted
68 mov r0,#6 ;Allocate RMA space
69 swi "OS_Module" ;Try to allocate anyway
70 mov r1,r2 ;Keep pointer to RMA block
72 ; --- Copy the program across and decrypt it ---
74 adr r0,ts__image+4 ;Point to encrypted image
75 ldr r3,FNlitw(ts__imageEnd-ts__image-4)
76 ldr r12,FNlitw(&1b9a7f83) ;IV for decryption process
78 .tSupt_init05 ldr r4,[r0],#4 ;Get a word from the image
79 eor r14,r12,r4,ror #24 ;Decrypt the word
80 str r14,[r2],#4 ;Store the word in the block
81 mov r12,r4 ;Update IV from ciphertext
82 subs r3,r3,#4 ;Decrement the size counter
83 bgt tSupt_init05 ;More to do -- loop
85 ; --- Be friendly to StrongARM ---
87 ; By spooky coincidence, these registers are set up already.
89 mov r0,#1 ;Synchronise address range
90 sub r2,r2,#4 ;Because Acorn are weird...
91 swi XOS_SynchroniseCodeAreas ;Go and do that, please
93 ; --- Initialise the image ---
95 mov r14,pc ;Get return address
96 add pc,r1,#0 ;Call the initialise routine
97 str r1,ts__image ;Store base address away
98 ldmfd r13!,{r0-r4,r12,pc}^ ;Return to caller
100 ; --- It's already resident ---
102 .tSupt_init10 cmp r2,#ts_version ;Which version is in there?
103 strcs r1,ts__image ;New enough -- store base
104 ldmcsfd r13!,{r0-r4,r12,pc}^ ;And return to caller
106 adr r0,ts__tooOld ;Point to error message
107 swi "OS_GenerateError" ;And raise merry hell
108 ldmfd r13!,{r0-r4,r12,pc}^ ;Return to caller
111 dcb "Tearoff support code is too old"
116 ; --- tearSupport_opened ---
118 ; On entry; R0 == task handle of task which opened tearoff menu
122 ; Use; Informs TearSupport that a transient tearoff menu has been
123 ; opened, and which task owns the menu.
125 FNexport("tearSupport_opened")
134 ; --- tearSupport_closed ---
140 ; Use; Informs TearSupport that a transient tearoff menu has been
141 ; closed, and that support is no longer required for it.
143 FNexport("tearSupport_closed")
152 ; --- tearSupport_switch ---
154 ; On entry; R0 == 1 to disable, 0 to enable trapping
158 ; Use; Enables or disables trapping of Wimp_CreateMenu while a
159 ; transient tearoff menu is open. This is intended to allow
160 ; use of Wimp_CreateMenu by the transient tearoff owner while
161 ; a transient tearoff is open (e.g. to close Wimp menus).
163 FNexport("tearSupport_switch")
172 ;----- The actual TearoffSupport code ---------------------------------------
174 ; --- Structure of the code ---
176 ; Since this chunk is going to be copied into the RMA, we need to be able to
177 ; interface with it. We stick a branch table on the beginning and encrypt
182 .ts__image dcd ts__wSize+ts__wSpace-ts__image-4
189 ;----- Initialisation -------------------------------------------------------
197 ; Use; Initialises the TearSupport system.
199 .ts_init stmfd r13!,{r0-r2,r14} ;Stack link register nicely
200 FNadrl (r12,ts__wSpace) ;Find workspace address
201 mov r0,#0 ;A nice 0 value
202 str r0,[r12,#ts_useCount] ;Stuff it in the usage count
203 str r0,[r12,#ts_owner] ;No task using me yet
204 strb r0,[r12,#ts_swiCaught] ;Remember we're not on SWIV
206 mov r0,#ChangeEnvV ;Trap OS_ChangeEnvironment
207 adr r1,ts_changeEnv ;Point to my handler
208 mov r2,r12 ;Pass my workspace pointer
209 swi "XOS_Claim" ;Claim the vector nicely
211 ; --- Read the OS version ---
213 mov r0,#129 ;Load the OS version number
214 mov r1,#0 ;Set up OS_Byte arguments
215 mov r2,#255 ;For most obscure OS call
216 swi "OS_Byte" ;Read the version number
217 strb r1,[r12,#ts_osVersion] ;Save this away for later
219 ; --- I think that's it ---
221 ldmfd r13!,{r0-r2,pc}^ ;Return to caller happy
229 ; On exit; V clear if unloaded OK, otherwise V set
231 ; Use; Attempts to remove TearSupt from memory, to replace it with
232 ; a later version. If we can't close down, because we're in
233 ; use, we return an error.
235 .ts_unload bic r14,r14,#&10000000 ;Clear the V flag
236 stmfd r13!,{r0-r2,r14} ;Save some registers
237 FNadrl (r12,ts__wSpace) ;Find the workspace address
239 ; --- Free all the vectors ---
241 mov r0,#ChangeEnvV ;Trap OS_ChangeEnvironment
242 adr r1,ts_changeEnv ;Point to my handler
243 mov r2,r12 ;Pass my workspace pointer
244 swi "XOS_Release" ;Let go of that
246 bl ts_closed ;Pretend the transient closed
248 ; --- Deallocate my memory ---
250 ; This is a bit tricky, because I'm in it. I have to
251 ; copy a bit of myself onto the stack, and call that. Yuk.
253 adr r14,ts__return ;Point to return code
254 ldmia r14,{r0-r2} ;Load the code out
255 stmfd r13!,{r0-r2} ;Save it onto the stack
257 adr r2,ts__image+4 ;Point to the block base
258 mov r0,#7 ;Deallocate an RMA block
259 mov pc,r13 ;Call return code
261 .ts__return swi "OS_Module" ;Deallocate the memory
262 add r13,r13,#12 ;Point to stack frame
263 ldmfd r13!,{r0-r2,pc}^ ;Return without mishap
267 ; --- Vector numbers ---
276 ; On entry; R0 == task handle attempting to open tearoff transient
280 ; Use; Informs the TearSupt system that a task is opening a
281 ; transient tearoff menu.
284 .ts_opened stmfd r13!,{r0-r2,r11,r12,r14}
285 mov r11,r0 ;Look after the task handle
286 FNadrl (r12,ts__wSpace) ;Find my workspace address
288 ; --- Make sure we need to do this ---
290 ldr r0,[r12,#ts_useCount] ;Get the counter
291 cmp r0,#0 ;Am I currently running?
292 bne ts_opened00 ;Yes -- skip this little bit
294 ; --- Claim event vector ---
296 swi "XOS_Mouse" ;Get the current mouse pos
297 str r2,[r12,#ts_mouseState] ;Store it in workspace
299 mov r0,#MouseV ;Vector number
300 adr r1,ts_mouse ;Point to event handler
301 mov r2,r12 ;Point to workspace
302 swi "XOS_Claim" ;Try it and see
304 mov r0,#InsV ;Vector number
305 adr r1,ts_insert ;Point to event handler
306 mov r2,r12 ;Point to workspace
307 swi "XOS_Claim" ;Try it and see
310 ldmvsfd r13!,{r1,r2,r11,r12,pc} ;Can't see this failing, but
314 ; --- Update my tables and leave ---
316 .ts_opened00 ldr r0,[r12,#ts_owner] ;Who's using me at the mo?
317 cmp r0,r11 ;Is it someone else?
318 cmpne r0,#0 ;Make sure s'not a ghost
319 blne ts_escape_cb ;Tell the appl to close
320 str r11,[r12,#ts_owner] ;Store the new handle
322 ldr r0,[r12,#ts_useCount] ;Find my usage counter
323 add r0,r0,#1 ;Bump it
324 str r0,[r12,#ts_useCount] ;And store it back for later
326 ldmfd r13!,{r0-r2,r11,r12,pc}^
336 ; Use; Informs TearSupt that the transient tearoff has been closed.
337 ; If no transient is open, no action is performed.
339 .ts_closed stmfd r13!,{r12,r14} ;Save some registers
340 adr r12,ts__wSpace ;Find my workspace address
341 ldr r14,[r12,#ts_useCount] ;Find out my counter thing
342 cmp r14,#0 ;Is it zero?
343 ldmeqfd r13!,{r12,pc}^ ;Someone's being silly
344 subs r14,r14,#1 ;Decrement the counter
345 str r14,[r12,#ts_useCount] ;Store for later
346 ldmnefd r13!,{r12,pc}^ ;Return if still nonzero
348 ; --- Remove handlers and things ---
350 stmfd r13!,{r0-r2} ;Save some more registers
351 bl ts_swiRelease ;Release SWI vector patch
353 mov r0,#InsV ;Vector number
354 adr r1,ts_insert ;Point to handler code
355 mov r2,r12 ;Point to workspace
356 swi "XOS_Release" ;Let go of the vector
358 mov r0,#MouseV ;Vector number
359 adr r1,ts_mouse ;Point to handler code
360 mov r2,r12 ;Point to workspace
361 swi "XOS_Release" ;Let go of the vector
363 ldmfd r13!,{r0-r2,r12,pc}^ ;Return to caller
369 ; On entry; R0 == 1 to suspend trapping, 0 to unsuspend
373 ; Use; Enables or disables trapping of Wimp_CreateMenu, to enable
374 ; TMS implementations to close Wimp menus where necessary.
376 .ts_switch stmfd r13!,{r12,r14} ;Save some registers
377 adr r12,ts__wSpace ;Find my workspace
378 strb r0,[r12,#ts_swiThreaded] ;Disable the SWI patch
379 ldmfd r13!,{r12,pc}^ ;And return to caller
383 ;----- The handlers and callbacks -------------------------------------------
385 ; --- ts_changeEnv ---
387 ; On entry; As for OS_ChangeEnvironment
389 ; On exit; R0 == address of TearSupt, if R0 == -1 on entry
391 ; Use; Traps odd calls to OS_ChangeEnvironment to allow TearSupt
394 .ts_changeEnv cmn r0,#1 ;Is it our special env code?
395 adreq r1,ts__image+4 ;Yes -- return ptr to base
396 moveq r2,#ts_version ;And get the version number
397 ldmeqfd r13!,{pc}^ ;And claim the vector
398 movs pc,r14 ;Otherwise pass on vector
402 ; On entry; R0 == byte inserted into buffer
403 ; R1 == buffer number
407 ; Use; Inspects all insertions into buffers, and traps attempts
408 ; to insert escape keypresses, converting these to requests
409 ; to close the current transient tearoff.
411 .ts_insert cmp r0,#27 ;Make sure it's an escape
412 cmpeq r1,#0 ;And it's from the keyboard
413 movnes pc,r14 ;If not, give up and leave
414 stmfd r13!,{r14} ;Save a register
415 ldr r14,[r12,#ts_owner] ;Get my owner's ID
416 cmn r14,#1 ;Is it valid?
417 ldmeqfd r13!,{pc}^ ;No -- then return to caller
419 ; --- Mess about with the processor status ---
421 stmfd r13!,{r0,r1,r8} ;Store registers away
422 mov r8,pc ;Get PC with PSR
423 teqp pc,#3 ;Enter SVC mode
424 mov r0,r0 ;Avoid contention of R13/R14
425 stmfd r13!,{r14} ;Stack return address
426 adr r0,ts_escape_cb ;Point to callback routine
427 mov r1,r12 ;Point to workspace
428 swi "XOS_AddCallBack" ;Add the callback routine
429 ldmfd r13!,{r14} ;Restore R14_svc
430 teqp r8,#0 ;Restore old PSR values
431 mov r0,r0 ;No-op to keep ARM happy
432 ldmfd r13!,{r0,r1,r8,pc}^ ;Return to caller
442 ; Use; Inspects all mouse positions returned by OS_Mouse, and sends
443 ; them to the current transient owner.
445 .ts_mouse stmfd r13!,{r10-r12,r14} ;Stack some registers
447 ; --- Pass on the vector, leaving ourself on the stack ---
449 ; Modified from Acorn's code to avoid dependency on
450 ; possibly non-compatible PC+12 behaviour.
452 mov r14,pc ;Get current program counter
453 add r14,r14,#12 ;Point at our processing code
454 stmfd r13!,{r14} ;Make us get called back
455 add r12,r13,#4 ;Point to saved R10 on stack
456 ldmia r12,{r10-r12,pc} ;Call next routine on vector
458 ; --- The vector has now completed nicely ---
460 ldr r12,[r13,#8] ;Get my stacked r12
462 stmfd r13!,{r0-r3} ;Stack some registers for me
463 ldr r0,[r12,#ts_mouseState] ;Get old mouse state
464 str r2,[r12,#ts_mouseState] ;Store as the old state
465 bics r2,r2,r0 ;Find out what changed
466 ldmeqfd r13!,{r0-r3,r10-r12,r14,pc} ;If nothing then return
468 ; --- A button was clicked -- tell our client ---
470 add r1,r12,#ts_message+20 ;Point to message buffer
471 swi "XWimp_GetPointerInfo" ;Get pointer info
472 sub r1,r1,#20 ;Point to base of message
473 mov r0,#40 ;Length of message
474 str r0,[r1,#0] ;Store in message block
475 mov r0,#0 ;This isn't a reply
476 str r0,[r1,#12] ;So zero the your_ref
477 ldr r0,FNlitw(&4A340) ;The magic message number
478 str r0,[r1,#16] ;Fill it in
479 mov r0,#17 ;Don't want it bouncing
480 ldr r2,[r12,#ts_owner] ;Find my owner application
481 swi "XWimp_SendMessage" ;Send it the message
483 ldmfd r13!,{r0-r3,r10-r12,r14,pc} ;We're a happy bunny
487 ; --- ts_escape_cb ---
493 ; Use; Sends a message to the transient tearoff owner, to tell
494 ; it to close the transient. This is usually as a result of
495 ; the user pressing escape or another task calling
498 .ts_escape_cb stmfd r13!,{r0-r3,r14} ;Save some registers
499 add r1,r12,#ts_message ;Point to message buffer
500 mov r0,#20 ;Length of message
501 str r0,[r1,#0] ;Store in message block
502 mov r0,#0 ;This isn't a reply
503 str r0,[r1,#12] ;So zero the your_ref
504 ldr r0,FNlitw(&4A341) ;The magic message number
505 str r0,[r1,#16] ;Fill it in
506 mov r0,#17 ;Don't want it bouncing
507 ldr r2,[r12,#ts_owner] ;Find my owner application
508 swi "XWimp_SendMessage" ;Send it the message
509 mvn r0,#0 ;Stop it happening again
510 str r0,[r12,#ts_owner] ;Won't happen now!
511 ldmfd r13!,{r0-r3,pc}^ ;Don't worry. Be happy.
515 ;----- SWI vector handling --------------------------------------------------
517 ; Warning; this section contains some really heavy stuff. If you're nervous,
518 ; you may wish to seek medical advice before looking at this code. We can't
519 ; accept any responsibility for any loss or disability incurred as a result
520 ; of reading this source.
522 ; --- ts_swiClaim ---
528 ; Use; Sets up the SWI vector patch.
530 .ts_swiClaim stmfd r13!,{r0-r3,r14} ;Stack some registers
531 ldrb r0,[r12,#ts_swiCaught] ;Have we done it already?
532 cmp r0,#0 ;Just check
533 ldmnefd r13!,{r0-r3,pc}^ ;If so, just carry on
535 ldrb r14,[r12,#ts_osVersion] ;Get the OS version
536 cmp r14,#&a5 ;Is this a RISC PC?
537 bcs ts_swiClaim50 ;Yes -- do special things
539 mov r0,#0 ;Point to hardware vectors
540 ldr r1,[r0,#&08] ;Get the SWIV instruction
541 str r1,[r12,#ts_oldSWIinstr] ;Remember this instruction
542 and r2,r1,#&0F000000 ;Get the basic instruction
543 cmp r2,#&0A000000 ;Is it a branch?
544 beq ts_swiClaim00 ;Yes -- handle that
546 ; --- Mangle an LDR PC,[PC,#...] ---
548 ldr r2,FNlitw(&FFF) ;Mask off LDR bits
549 and r2,r1,r2 ;Get the offset of LDR
550 tst r1,#1<<23 ;Check the sign bit
551 addne r3,r2,#&10 ;If additive, then add offset
552 rsbeq r3,r2,#&10 ;If subtractive, subtract ;-)
553 str r3,[r12,#ts_oldSWIaddr] ;Store this address away
554 b ts_swiClaim01 ;Now insert our branch code
556 ; --- Mangle a B ... ---
558 .ts_swiClaim00 bic r2,r1,#&FF000000 ;Clear instruction bits
559 add r2,r2,#4 ;Take pipeline into account
560 mov r2,r2,lsl #2 ;Word align the result
561 bic r2,r2,#&FC000003 ;Turn it into a real address
562 str r2,[r12,#ts_dummySWIptr] ;Store this in our pointer
563 add r3,r12,#ts_dummySWIptr ;Point to this pointer
564 str r3,[r12,#ts_oldSWIaddr] ;Store *this* address away
566 ; --- Now insert our own instruction ---
568 .ts_swiClaim01 adr r1,ts_swiClaimer ;Point to the routine
569 mov r1,r1,lsr #2 ;Shift off bottom zero bits
570 sub r1,r1,#4 ;Adjust the address of branch
571 orr r1,r1,#&EA000000 ;Make it a branch instr
572 str r1,[r12,#ts_newSWIinstr] ;Store this new instruction
573 swi "OS_EnterOS" ;We're messing with SWI vect
574 str r1,[r0,#8] ;This is now the SWI vector
575 teqp pc,#0 ;Back to user mode
576 mov r0,r0 ;No-op for strange reasons
577 mov r0,#1 ;We've now patched SWIV
578 strb r0,[r12,#ts_swiCaught] ;So remember this
579 mov r0,#0 ;Not yet threaded, though
580 strb r0,[r12,#ts_swiThreaded]
581 ldmfd r13!,{r0-r3,pc}^ ;Return to caller
583 ; --- We have an OS call to do this ---
585 .ts_swiClaim50 mov r0,#2 ;Claim SWI vector
586 orr r0,r0,#256 ;Set the `claim' flag
587 adr r1,ts_swi610 ;Point to handler routine
588 swi "XOS_IntOff" ;Stop all SWIs for a bit
589 swi XOS_ClaimProcessorVector
590 str r1,[r12,#ts_dummySWIptr] ;Save old handler address
591 add r3,r12,#ts_dummySWIptr ;Point to this pointer
592 str r3,[r12,#ts_oldSWIaddr] ;And store *this* address
593 swi "XOS_IntOn" ;We can handle SWIs again now
595 mov r0,#1 ;We've now patched SWIV
596 strb r0,[r12,#ts_swiCaught] ;So remember this
597 mov r0,#0 ;Not yet threaded, though
598 strb r0,[r12,#ts_swiThreaded]
600 ldmfd r13!,{r0-r3,pc}^ ;Return to caller
604 ; --- ts_swiRelease ---
608 ; On exit; CS if patch removed OK, else CC
610 ; Use; Attempts to remove the SWI vector patch. If this can't be
611 ; done, then the patch is left in.
613 .ts_swiRelease stmfd r13!,{r0-r2,r14} ;Stack registers
614 ldrb r0,[r12,#ts_swiCaught] ;Is the vector trapped?
615 cmp r0,#0 ;Quick check...
616 ldmeqfd r13!,{r0-r2,pc}^ ;No -- return then
618 ; --- Check if this is a RISC PC ---
620 ldrb r0,[r12,#ts_osVersion] ;Load the OS version
621 cmp r0,#&a5 ;Is this a RISC PC
622 bcs ts_swiRel50 ;Yes -- do different things
624 mov r0,#0 ;Point to hardware vectors
625 ldr r1,[r0,#8] ;Get SWI vector instruction
626 ldr r2,[r12,#ts_newSWIinstr] ;Get our one
627 cmp r1,r2 ;Are they the same?
628 bne ts_swiRel90 ;No -- couldn't reset it
630 ldr r1,[r12,#ts_oldSWIinstr] ;Get the old version then
631 swi "OS_EnterOS" ;We're messing with SWI vect
632 str r1,[r0,#8] ;Reinstate the old vector
633 teqp pc,#0 ;Back to user mode
634 mov r0,r0 ;Wait for things to settle
635 strb r0,[r12,#ts_swiCaught] ;SWIV no longer patched
636 ldmfd r13!,{r0-r2,r14} ;Return to caller
637 orrs pc,r14,#1<<29 ;Setting C to say *YES*
639 ; --- Release SWI vector using OS call ---
641 .ts_swiRel50 mov r0,#2 ;Releasing the SWI vector
642 ldr r1,[r12,#ts_dummySWIptr] ;Load address of old claimer
643 adr r2,ts_swi610 ;Point to expected handler
644 swi XOS_ClaimProcessorVector
645 bvs ts_swiRel90 ;Error -- couldn't do it
647 mov r14,#0 ;Clear claimed flag
648 strb r14,[r12,#ts_swiCaught] ;SWIV no longer patched
649 ldmfd r13!,{r0-r2,r14} ;Return to caller
650 orrs pc,r14,#1<<29 ;Setting C to say *YES*
652 ; --- Couldn't do it ---
654 .ts_swiRel90 ldmfd r13!,{r0-r2,r14} ;Restore registers
655 bics pc,r14,#1<<29 ;But clear C on exit
661 ; On entry; R0-R8 == arguments to SWI
662 ; R9-R12 == random values from the OS
663 ; R13 == supervisor stack pointer
664 ; R14 == return address from client
666 ; On exit; R0-R8 == returned from SWI
667 ; R9-R13 *AND SPSR_svc* preserved
669 ; Use; Intercepts all SWI calls in the system, catching
670 ; Wimp_CreateMenus and informing the transient owner of them.
672 .ts_swi610 stmfd r13!,{r10-r12,r14,pc} ;Stack some registers
674 ; --- Move into 26 bit mode ---
676 dcd &e14fb000 ;mrs r11,spsr_all
677 stmfd r13!,{r11} ;Save this on the stack
678 and r12,r11,#&f0000003 ;Get the processor status
679 orr r14,r14,r12 ;Add it to the R14 value
680 and r12,r11,#&c0 ;Get the interrupt flags
681 orr r14,r14,r12,lsl #20 ;Put them into R14 too
682 dcd &e10fb000 ;mrs r11,cpsr_all
683 bic r11,r11,#&1f ;Clear all the mode bits
684 orr r11,r11,#&03 ;Set SVC_26
685 dcd &e129f00b ;msr cpsr_all,r11
687 ; --- Now find out about the SWI ---
689 adr r12,ts__wSpace ;Point to workspace pointer
690 ldrb r10,[r12,#ts_swiThreaded] ;Is this routine threaded?
691 cmp r10,#0 ;Check now, or forever...
692 bne ts_swi610_00 ;If so, skip onwards
693 bic r10,r14,#&FC000003 ;Mask off saved PSR bits
694 ldr r11,[r10,#-4] ;Get SWI instruction
695 ldr r10,FNlitw(&FFF20000) ;Mask off silly SWI bits
696 bic r11,r11,r10 ;Get the pure SWI number
697 ldr r10,FNlitw(FNswiNum("Wimp_CreateMenu"))
698 cmp r10,r11 ;See if it's interesting
699 beq ts_swi610_10 ;Yes -- process it nicely
701 .ts_swi610_00 ldmfd r13!,{r14} ;Load the saved SPSR
702 dcd &e169f00e ;msr spsr_all,r14
704 ldr r14,[r12,#ts_oldSWIaddr] ;Point to old pointer
705 ldr r14,[r14,#0] ;Dereference the pointer
706 str r14,[r13,#16] ;Overwrite PC on the stack
707 ldmfd r13!,{r10-r12,r14,pc} ;Pass on to real SWI routine
709 ; --- Wimp_CreateMenu handling ---
711 .ts_swi610_10 mov r10,#1 ;Set the threaded flag
712 strb r10,[r12,#ts_swiThreaded] ;Remember we're in here
714 bl ts_escape_cb ;Send out the close message
716 .ts_swi610_01 mov r10,#0 ;Not threaded any more
717 strb r10,[r12,#ts_swiThreaded] ;Store this for others
718 b ts_swi610_00 ;And continue main thread
722 ; --- ts_swiClaimer ---
724 ; On entry; R0-R8 == arguments to SWI
725 ; R9-R12 == random values from the OS
726 ; R13 == supervisor stack pointer
727 ; R14 == return address from client
729 ; On exit; R0-R8 == returned from SWI
732 ; Use; Intercepts all SWI calls in the system, catching
733 ; Wimp_CreateMenus and informing the transient owner of them.
735 .ts_swiClaimer stmfd r13!,{r10-r12,r14,pc} ;Stack some registers
736 adr r12,ts__wSpace ;Point to workspace pointer
737 ldrb r10,[r12,#ts_swiThreaded] ;Is this routine threaded?
738 cmp r10,#0 ;Check now, or forever...
739 bne ts_swiClaimer00 ;If so, skip onwards
740 bic r10,r14,#&FC000003 ;Mask off saved PSR bits
741 ldr r11,[r10,#-4] ;Get SWI instruction
742 ldr r10,FNlitw(&FFF20000) ;Mask off silly SWI bits
743 bic r11,r11,r10 ;Get the pure SWI number
744 ldr r10,FNlitw(FNswiNum("Wimp_CreateMenu"))
745 cmp r10,r11 ;See if it's interesting
746 beq ts_swiClaimer10 ;Yes -- process it nicely
749 ldr r14,[r12,#ts_oldSWIaddr] ;Point to old pointer
750 ldr r14,[r14,#0] ;Dereference the pointer
751 str r14,[r13,#16] ;Overwrite PC on the stack
752 ldmfd r13!,{r10-r12,r14,pc} ;Pass on to real SWI routine
754 ; --- Wimp_CreateMenu handling ---
757 mov r10,#1 ;Set the threaded flag
758 strb r10,[r12,#ts_swiThreaded] ;Remember we're in here
760 bl ts_escape_cb ;Send out the close message
763 mov r10,#0 ;Not threaded any more
764 strb r10,[r12,#ts_swiThreaded] ;Store this for others
765 b ts_swiClaimer00 ;And continue main thread
774 ts_useCount =FNws_word
776 ts_mouseState =FNws_word
777 ts_newMouse =FNws_word
778 ts_oldSWIaddr =FNws_word
779 ts_dummySWIptr =FNws_word
780 ts_oldSWIinstr =FNws_word
781 ts_newSWIinstr =FNws_word
782 ts_swiCaught =FNws_byte
783 ts_swiThreaded =FNws_byte
784 ts_osVersion =FNws_byte
786 ts_message =FNws (40)
791 PRINT '"Encrypting...";
793 REM --- Encrypt the RMA resident section ---
796 FOR i%=ts__image+4 TO ts__imageEnd STEP 4
797 x%=i%!(O%-P%) EOR iv%
798 x%=(x%>>>8) OR (x%<<24)
810 SYS "OS_SWINumberFromString",,swi$ TO swin%