Create readable text `.bas' for each tokenized BASIC `,ffb' file.
[ssr] / StraySrc / Libraries / Core / TearSupt / bs / tearSupt.bas
1 REM
2 REM tearSupt.bs
3 REM
4 REM TearoffSupport code (encrypted)
5 REM
6 REM © 1994-1998 Straylight
7 REM
8
9 REM ----- Licensing note ----------------------------------------------------
10 REM
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).
13 REM
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)
17 REM any later version
18 REM
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.
23 REM
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.
27
28 LIBRARY "libs:BAS"
29
30 ON ERROR ERROR 0,REPORT$+" ["+STR$(ERL)+"]"
31 PROCbas_init
32 PROCbas_aofInit(&4000)
33
34 XOS_ClaimProcessorVector=&20069
35 XOS_SynchroniseCodeAreas=&2006E
36
37 PRINT "Assembling...";
38
39 ts_version=110
40
41 FOR 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 ]
269 MouseV = &1A
270 InsV = &14
271 ChangeEnvV = &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
774 ts_useCount =FNws_word
775 ts_owner =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
785 PROCws_align
786 ts_message =FNws (40)
787 ts__wSize =FNws (0)
788
789 NEXT
790
791 PRINT '"Encrypting...";
792
793 REM --- Encrypt the RMA resident section ---
794
795 iv%=&1b9a7f83
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)
799 i%!(O%-P%)=x%
800 iv%=x%
801 NEXT
802
803 PRINT '"Saving...";
804 PROCbas_aofSave
805 PRINT '"Done"
806 END
807
808 DEF FNswiNum(swi$)
809 LOCAL swin%
810 SYS "OS_SWINumberFromString",,swi$ TO swin%
811 =swin%
812