Create readable text `.bas' for each tokenized BASIC `,ffb' file.
[ssr] / StraySrc / Libraries / Core / TearSupt / bs / tearSupt.bas
CommitLineData
c1b567d8
MW
1REM
2REM tearSupt.bs
3REM
4REM TearoffSupport code (encrypted)
5REM
6REM © 1994-1998 Straylight
7REM
8
9REM ----- Licensing note ----------------------------------------------------
10REM
11REM This file is part of Straylight's Tearoff Menu System (TMS), but it's
12REM distributed with Straylight's core libraries (corelib).
13REM
14REM TMS is free software; you can redistribute it and/or modify
15REM it under the terms of the GNU General Public License as published by
16REM the Free Software Foundation; either version 2, or (at your option)
17REM any later version
18REM
19REM TMS is distributed in the hope that it will be useful,
20REM but WITHOUT ANY WARRANTY; without even the implied warranty of
21REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22REM GNU General Public License for more details.
23REM
24REM You should have received a copy of the GNU General Public License
25REM along with Corelib. If not, write to the Free Software Foundation,
26REM 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27
28LIBRARY "libs:BAS"
29
30ON ERROR ERROR 0,REPORT$+" ["+STR$(ERL)+"]"
31PROCbas_init
32PROCbas_aofInit(&4000)
33
34XOS_ClaimProcessorVector=&20069
35XOS_SynchroniseCodeAreas=&2006E
36
37PRINT "Assembling...";
38
39ts_version=110
40
41FOR o=4 TO 6 STEP 2
42[ opt o
43 FNpass
44
45;----- TearoffSupport interface code ----------------------------------------
46
47 FNarea("Asm$$Code","CODE,READONLY")
48
49; --- tearSupport_init ---
50;
51; On entry; --
52;
53; On exit; --
54;
55; Use; Initialises tearSupport
56
57 FNexport("tearSupport_init")
58.tearSupport_init
59
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
64
65 ; --- We need to set up the RMA block ---
66
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
71
72 ; --- Copy the program across and decrypt it ---
73
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
77
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
84
85 ; --- Be friendly to StrongARM ---
86 ;
87 ; By spooky coincidence, these registers are set up already.
88
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
92
93 ; --- Initialise the image ---
94
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
99
100 ; --- It's already resident ---
101
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
105
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
109
110.ts__tooOld dcd 1
111 dcb "Tearoff support code is too old"
112 dcb 0
113
114 FNltorg
115
116; --- tearSupport_opened ---
117;
118; On entry; R0 == task handle of task which opened tearoff menu
119;
120; On exit; --
121;
122; Use; Informs TearSupport that a transient tearoff menu has been
123; opened, and which task owns the menu.
124
125 FNexport("tearSupport_opened")
126.tearSupport_opened
127
128 stmfd r13!,{r12,r14}
129 ldr r12,ts__image
130 mov r14,pc
131 add pc,r12,#4
132 ldmfd r13!,{r12,pc}^
133
134; --- tearSupport_closed ---
135;
136; On entry; --
137;
138; On exit; --
139;
140; Use; Informs TearSupport that a transient tearoff menu has been
141; closed, and that support is no longer required for it.
142
143 FNexport("tearSupport_closed")
144.tearSupport_closed
145
146 stmfd r13!,{r12,r14}
147 ldr r12,ts__image
148 mov r14,pc
149 add pc,r12,#8
150 ldmfd r13!,{r12,pc}^
151
152; --- tearSupport_switch ---
153;
154; On entry; R0 == 1 to disable, 0 to enable trapping
155;
156; On exit; --
157;
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).
162
163 FNexport("tearSupport_switch")
164.tearSupport_switch
165
166 stmfd r13!,{r12,r14}
167 ldr r12,ts__image
168 mov r14,pc
169 add pc,r12,#12
170 ldmfd r13!,{r12,pc}^
171
172;----- The actual TearoffSupport code ---------------------------------------
173
174; --- Structure of the code ---
175;
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
178; everything else.
179
180 FNnoReloc
181
182.ts__image dcd ts__wSize+ts__wSpace-ts__image-4
183 b ts_init
184 b ts_opened
185 b ts_closed
186 b ts_switch
187 b ts_unload
188
189;----- Initialisation -------------------------------------------------------
190
191; --- ts_init ---
192;
193; On entry; --
194;
195; On exit; --
196;
197; Use; Initialises the TearSupport system.
198
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
205
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
210
211 ; --- Read the OS version ---
212
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
218
219 ; --- I think that's it ---
220
221 ldmfd r13!,{r0-r2,pc}^ ;Return to caller happy
222
223 FNltorg
224
225; --- ts_unload ---
226;
227; On entry; --
228;
229; On exit; V clear if unloaded OK, otherwise V set
230;
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.
234
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
238
239 ; --- Free all the vectors ---
240
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
245
246 bl ts_closed ;Pretend the transient closed
247
248 ; --- Deallocate my memory ---
249 ;
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.
252
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
256
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
260
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
264
265 FNltorg
266
267; --- Vector numbers ---
268]
269MouseV = &1A
270InsV = &14
271ChangeEnvV = &1E
272[ opt o
273
274; --- ts_opened ---
275;
276; On entry; R0 == task handle attempting to open tearoff transient
277;
278; On exit; --
279;
280; Use; Informs the TearSupt system that a task is opening a
281; transient tearoff menu.
282
283
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
287
288 ; --- Make sure we need to do this ---
289
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
293
294 ; --- Claim event vector ---
295
296 swi "XOS_Mouse" ;Get the current mouse pos
297 str r2,[r12,#ts_mouseState] ;Store it in workspace
298
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
303
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
308
309 addvs r13,r13,#4
310 ldmvsfd r13!,{r1,r2,r11,r12,pc} ;Can't see this failing, but
311
312 bl ts_swiClaim
313
314 ; --- Update my tables and leave ---
315
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
321
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
325
326 ldmfd r13!,{r0-r2,r11,r12,pc}^
327
328 FNltorg
329
330; --- ts_closed ---
331;
332; On entry; --
333;
334; On exit; --
335;
336; Use; Informs TearSupt that the transient tearoff has been closed.
337; If no transient is open, no action is performed.
338
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
347
348 ; --- Remove handlers and things ---
349
350 stmfd r13!,{r0-r2} ;Save some more registers
351 bl ts_swiRelease ;Release SWI vector patch
352
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
357
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
362
363 ldmfd r13!,{r0-r2,r12,pc}^ ;Return to caller
364
365 FNltorg
366
367; --- ts_switch ---
368;
369; On entry; R0 == 1 to suspend trapping, 0 to unsuspend
370;
371; On exit; --
372;
373; Use; Enables or disables trapping of Wimp_CreateMenu, to enable
374; TMS implementations to close Wimp menus where necessary.
375
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
380
381 FNltorg
382
383;----- The handlers and callbacks -------------------------------------------
384
385; --- ts_changeEnv ---
386;
387; On entry; As for OS_ChangeEnvironment
388;
389; On exit; R0 == address of TearSupt, if R0 == -1 on entry
390;
391; Use; Traps odd calls to OS_ChangeEnvironment to allow TearSupt
392; to be located.
393
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
399
400; --- ts_insert ---
401;
402; On entry; R0 == byte inserted into buffer
403; R1 == buffer number
404;
405; On exit; --
406;
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.
410
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
418
419 ; --- Mess about with the processor status ---
420
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
433
434 FNltorg
435
436; --- ts_mouse ---
437;
438; On entry; --
439;
440; On exit; --
441;
442; Use; Inspects all mouse positions returned by OS_Mouse, and sends
443; them to the current transient owner.
444
445.ts_mouse stmfd r13!,{r10-r12,r14} ;Stack some registers
446
447 ; --- Pass on the vector, leaving ourself on the stack ---
448 ;
449 ; Modified from Acorn's code to avoid dependency on
450 ; possibly non-compatible PC+12 behaviour.
451
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
457
458 ; --- The vector has now completed nicely ---
459
460 ldr r12,[r13,#8] ;Get my stacked r12
461
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
467
468 ; --- A button was clicked -- tell our client ---
469
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
482
483 ldmfd r13!,{r0-r3,r10-r12,r14,pc} ;We're a happy bunny
484
485 FNltorg
486
487; --- ts_escape_cb ---
488;
489; On entry; --
490;
491; On exit; --
492;
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
496; Wimp_CreateMenu.
497
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.
512
513 FNltorg
514
515;----- SWI vector handling --------------------------------------------------
516;
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.
521
522; --- ts_swiClaim ---
523;
524; On entry; --
525;
526; On exit; --
527;
528; Use; Sets up the SWI vector patch.
529
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
534
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
538
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
545
546 ; --- Mangle an LDR PC,[PC,#...] ---
547
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
555
556 ; --- Mangle a B ... ---
557
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
565
566 ; --- Now insert our own instruction ---
567
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
582
583 ; --- We have an OS call to do this ---
584
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
594
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]
599
600 ldmfd r13!,{r0-r3,pc}^ ;Return to caller
601
602 FNltorg
603
604; --- ts_swiRelease ---
605;
606; On entry; --
607;
608; On exit; CS if patch removed OK, else CC
609;
610; Use; Attempts to remove the SWI vector patch. If this can't be
611; done, then the patch is left in.
612
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
617
618 ; --- Check if this is a RISC PC ---
619
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
623
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
629
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*
638
639 ; --- Release SWI vector using OS call ---
640
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
646
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*
651
652 ; --- Couldn't do it ---
653
654.ts_swiRel90 ldmfd r13!,{r0-r2,r14} ;Restore registers
655 bics pc,r14,#1<<29 ;But clear C on exit
656
657 FNltorg
658
659; --- ts_swi610 ---
660;
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
665;
666; On exit; R0-R8 == returned from SWI
667; R9-R13 *AND SPSR_svc* preserved
668;
669; Use; Intercepts all SWI calls in the system, catching
670; Wimp_CreateMenus and informing the transient owner of them.
671
672.ts_swi610 stmfd r13!,{r10-r12,r14,pc} ;Stack some registers
673
674 ; --- Move into 26 bit mode ---
675
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
686
687 ; --- Now find out about the SWI ---
688
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
700
701.ts_swi610_00 ldmfd r13!,{r14} ;Load the saved SPSR
702 dcd &e169f00e ;msr spsr_all,r14
703
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
708
709 ; --- Wimp_CreateMenu handling ---
710
711.ts_swi610_10 mov r10,#1 ;Set the threaded flag
712 strb r10,[r12,#ts_swiThreaded] ;Remember we're in here
713
714 bl ts_escape_cb ;Send out the close message
715
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
719
720 FNltorg
721
722; --- ts_swiClaimer ---
723;
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
728;
729; On exit; R0-R8 == returned from SWI
730; R9-R13 preserved
731;
732; Use; Intercepts all SWI calls in the system, catching
733; Wimp_CreateMenus and informing the transient owner of them.
734
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
747
748.ts_swiClaimer00
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
753
754 ; --- Wimp_CreateMenu handling ---
755
756.ts_swiClaimer10
757 mov r10,#1 ;Set the threaded flag
758 strb r10,[r12,#ts_swiThreaded] ;Remember we're in here
759
760 bl ts_escape_cb ;Send out the close message
761
762.ts_swiClaimer01
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
766
767 FNltorg
768
769.ts__wSpace
770.ts__imageEnd
771]
772
773 PROCws_start
774ts_useCount =FNws_word
775ts_owner =FNws_word
776ts_mouseState =FNws_word
777ts_newMouse =FNws_word
778ts_oldSWIaddr =FNws_word
779ts_dummySWIptr =FNws_word
780ts_oldSWIinstr =FNws_word
781ts_newSWIinstr =FNws_word
782ts_swiCaught =FNws_byte
783ts_swiThreaded =FNws_byte
784ts_osVersion =FNws_byte
785 PROCws_align
786ts_message =FNws (40)
787ts__wSize =FNws (0)
788
789NEXT
790
791PRINT '"Encrypting...";
792
793REM --- Encrypt the RMA resident section ---
794
795iv%=&1b9a7f83
796FOR i%=ts__image+4 TO ts__imageEnd STEP 4
797 x%=i%!(O%-P%) EOR iv%
798 x%=(x%>>>8) OR (x%<<24)
799 i%!(O%-P%)=x%
800 iv%=x%
801NEXT
802
803PRINT '"Saving...";
804PROCbas_aofSave
805PRINT '"Done"
806END
807
808DEF FNswiNum(swi$)
809LOCAL swin%
810SYS "OS_SWINumberFromString",,swi$ TO swin%
811=swin%
812