chiark / gitweb /
JPEG support and other fixes from Nick Clark
[ssr] / StraySrc / Libraries / Sapphire / s / ptr
1 ;
2 ; ptr.s
3 ;
4 ; Pointer changing and caret blinking (TMA)
5 ;
6 ; © 1994-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's Sapphire library.
12 ;
13 ; Sapphire is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
16 ; any later version.
17 ;
18 ; Sapphire is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 ; GNU General Public License for more details.
22 ;
23 ; You should have received a copy of the GNU General Public License
24 ; along with Sapphire.  If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27 ;----- Standard header ------------------------------------------------------
28
29                 GET     libs:header
30                 GET     libs:swis
31
32 ;----- External dependencies ------------------------------------------------
33
34                 GET     sapphire:event
35                 GET     sapphire:except
36                 GET     sapphire:idle
37                 GET     sapphire:resspr
38                 GET     sapphire:sapphire
39                 GET     sapphire:screen
40                 GET     sapphire:sprite
41                 GET     sapphire:string
42                 GET     sapphire:wimp
43
44 ;----- Main code ------------------------------------------------------------
45
46                 AREA    |Sapphire$$Code|,CODE,READONLY
47
48 ;----- Pointer shape changing -----------------------------------------------
49
50 ; --- ptr_setShape ---
51 ;
52 ; On entry:     R0 == sprite name
53 ;               R1 == x offset of hot spot
54 ;               R2 == y offset of hot spot
55 ;
56 ; On exit:      --
57 ;
58 ; Use:          Set the pointer sprite to the given name. The sprite area
59 ;               used is that returned from resspre_area.
60
61                 EXPORT  ptr_setShape
62 ptr_setShape    ROUT
63
64                 STMFD   R13!,{R0-R7,R12,R14}    ;Stack some registers
65                 WSPACE  ptr__wSpace             ;Get my workspace
66
67                 ; --- Try to find a good match for the mode ---
68
69                 MOV     R1,R0                   ;Get name in R1
70                 BL      screen_getInfo          ;Get mode information block
71                 MOV     R7,R0                   ;Remember its position
72                 MOV     R0,R11                  ;Put my buffer in R0
73                 BL      str_cpy                 ;Copy the string across
74
75                 MOV     R4,#'0'                 ;For ASCII conversion
76                 LDR     R1,[R7,#screen_dx]      ;Get x pixel size
77                 ADD     R1,R4,R1                ;Convert to ASCII pix size
78                 STRB    R1,[R0],#1              ;Store it in the buffer
79                 LDR     R1,[R7,#screen_dy]      ;Get y pixel size
80                 ADD     R1,R4,R1                ;Convert to ASCII pix size
81                 STRB    R1,[R0],#1              ;Store it in the buffer
82                 MOV     R1,#0
83                 STRB    R1,[R0]                 ;Stick a NULL on the end
84
85                 ; --- Does sprite exist (sprite call corrupts R0-R6) ---
86
87                 MOV     R0,#40                  ;Read sprite information
88                 MOV     R2,R11                  ;Pointer to sprite name
89                 BL      sprite_op               ;Does the sprite exist
90
91                 LDMIA   R13,{R2,R4,R5}          ;Get users name, x and y
92                 BVS     %10ptr_setShape         ;If sprite didn't exist...
93
94                 ; --- Now use the new sprite ---
95
96                 MOV     R2,R11                  ;Use this sprite name
97
98                 ; --- Alter the x and y offsets for new resolution ---
99
100                 LDR     R0,[R7,#screen_xEig]    ;Get the screen xEig
101                 MOV     R4,R4,LSL #1            ;Multiply by 2
102                 MOV     R4,R4,LSR R0            ;And shift down by xEig
103                 LDR     R0,[R7,#screen_yEig]    ;Get the screen yEig
104                 MOV     R5,R5,LSL #2            ;Multiply by 4
105                 MOV     R5,R5,LSR R0            ;And shift down by yEig
106
107 10ptr_setShape  MOV     R0,#36                  ;Set pointer shape
108                 MOV     R3,#2                   ;Pointer shape number
109                 MOV     R6,#0                   ;Scale factors
110                 MOV     R7,#0                   ;Pixel translation
111
112                 BL      sprite_op               ;Do the correct SpriteOp
113
114                 ; --- Alter my flags ---
115
116                 LDR     R0,ptr__flags           ;Get my flags
117                 ORR     R0,R0,#ptr__USERSET+ptr__NOTDEFAULT
118                 STR     R0,ptr__flags           ;Store the flags back
119
120                 ; --- Return to caller ---
121
122                 LDMFD   R13!,{R0-R7,R12,PC}^    ;Return to user
123
124                 LTORG
125
126 ; --- ptr_resetShape ---
127 ;
128 ; On entry:     --
129 ;
130 ; On exit:      --
131 ;
132 ; Use:          Resets the pointer shape to the default.
133
134                 EXPORT  ptr_resetShape
135 ptr_resetShape  ROUT
136
137                 STMFD   R13!,{R0,R12,R14}       ;Save some registers
138                 WSPACE  ptr__wSpace             ;Get my workspace
139
140                 ; --- Is the default pointer already on? ---
141
142                 LDR     R0,ptr__flags           ;Get my flags
143                 TST     R0,#ptr__NOTDEFAULT     ;Are we using default
144                 LDMEQFD R13!,{R0,R12,PC}^       ;Yes, return
145
146                 ; --- Alter the flags ---
147
148                 BIC     R0,R0,#ptr__NOTDEFAULT+ptr__USERSET
149                 STR     R0,ptr__flags           ;Store the flags
150
151                 ; --- Now reset the shape using *pointer (Yuck) ---
152
153                 ADR     R0,ptr__pointer         ;Point to command
154                 SWI     OS_CLI                  ;Execute it
155
156                 LDMFD   R13!,{R0,R12,PC}^       ;Return to user
157
158                 LTORG
159
160 ptr__pointer    DCB     "Pointer",0             ;*Pointer command string
161
162 ;----- Automatic pointer changing -------------------------------------------
163
164 ; --- ptr__idles ---
165 ;
166 ; On entry:     R12 == pointer to my workspace
167 ;
168 ; On exit:      --
169 ;
170 ; Use:          Called on idle events to try to change the pointer
171 ;               shape if it needs to.
172
173 ptr__idles      ROUT
174
175                 STMFD   R13!,{R0-R7,R14}        ;Stack some registers
176
177                 LDR     R0,ptr__flags           ;Get my flags
178                 TST     R0,#ptr__USERSET        ;Are we using user ptr?
179                 LDMNEFD R13!,{R0-R7,PC}^        ;Yes, return
180
181                 ; --- Is the pointer over an icon? ---
182
183                 MOV     R1,R11                  ;Use the scratch pad
184                 SWI     Wimp_GetPointerInfo     ;Get pointer info
185                 LDR     R0,[R1,#16]             ;Get icon under pointer
186                 LDR     R2,ptr__oldIcon         ;What were we over before?
187                 STR     R0,ptr__oldIcon         ;This is now previous icon
188                 CMP     R2,R0                   ;Are they the same
189                 LDMEQFD R13!,{R0-R7,PC}^        ;Yes -- return
190                 CMP     R0,#-1                  ;Is it the window background?
191                 BEQ     %90ptr__idles           ;Yes -- skip to the end
192
193                 ; --- Is this icon interesting? ---
194
195                 STR     R0,[R1,#4]              ;Store the icon number
196                 LDR     R2,[R1,#12]             ;Get the returned window hnd
197                 STR     R2,[R1,#0]              ;Store it at beginning
198                 SWI     Wimp_GetIconState       ;Get the state of the icon
199                 LDR     R2,[R1,#24]             ;Get the icon flags
200
201                 MOV     R7,R2,LSR#12            ;Get the button type
202                 AND     R7,R7,#15               ;...only
203
204                 TST     R2,#&100                ;Is it indirected?
205                 TSTNE   R2,#&01                 ;Is it a text icon?
206                 BEQ     %90ptr__idles           ;Not both -- return
207                 AND     R2,R2,#&1f0000          ;Get the ESG number
208                 CMP     R2,#&1f0000             ;Is it 31?
209                 BEQ     %90ptr__idles           ;Yes -- it's shaded
210
211                 LDR     R2,[R1,#32]             ;Get the validation string
212                 CMP     R2,#-1                  ;Does it exist?
213                 BEQ     %90ptr__idles           ;No -- return
214
215                 ; --- Now parse validation string for xp<name>,<x>,<y> ---
216                 ;
217                 ; This is based on a state drive parser with the following
218                 ; defined states:
219                 ;
220                 ;       0 == not in anything useful
221                 ;       1 == looking for xp
222                 ;       2 == reading sprite name
223                 ;       3 == reading x value
224                 ;       4 == reading y value
225                 ;       5 == finished
226
227                 MOV     R0,#1                   ;Set the current state to 1
228                 ADD     R3,R11,#20              ;Use this buffer
229                 MOV     R5,#0                   ;Current x value
230                 MOV     R6,#0                   ;Current y value
231
232                 ; --- All cases return to here ---
233
234 00ptr__idles    CMP     R0,#5                   ;Are we in state 5?
235                 BEQ     %70ptr__idles           ;Yes -- we're finished
236                 LDRB    R1,[R2],#1              ;Get a character
237                 CMP     R1,#31                  ;Is it a terminator
238                 BLE     %70ptr__idles           ;Yes -- we're finished
239
240                 ; --- case '\' ---
241
242                 CMP     R1,#'\'                 ;Is it the escape character?
243                 BNE     %10ptr__idles           ;No -- try next case
244                 LDRB    R4,[R2]                 ;Get the next byte
245                 CMP     R4,#31                  ;Is it a terminator
246                 MOVGT   R1,R4                   ;No -- use this
247                 ADDGT   R2,R2,#1                ;...and increment pointer
248                 CMP     R0,#1                   ;Are we in state 1?
249                 MOVEQ   R0,#0                   ;Yes -- go into state 0
250                 CMP     R0,#2                   ;Are we in state 2
251                 STREQB  R1,[R3],#1              ;Yes -- store the character
252                 B       %00ptr__idles           ;break
253
254                 ; --- case ';' ---
255
256 10ptr__idles    CMP     R1,#';'                 ;Is it a new command?
257                 BNE     %20ptr__idles           ;No -- try next case
258                 CMP     R0,#1                   ;Is the state greater than 1?
259                 MOVGT   R0,#5                   ;Yes -- state = 5
260                 MOVLE   R0,#1                   ;No -- state = 1
261                 B       %00ptr__idles           ;break
262
263                 ; --- case 'X' / 'x' ---
264
265 20ptr__idles    CMP     R1,#'X'                 ;Is is an 'X'?
266                 CMPNE   R1,#'x'                 ;Or an 'x'?
267                 BNE     %30ptr__idles           ;No -- try next case
268                 CMP     R0,#1                   ;Are we in state 1?
269                 BNE     %21ptr__idles           ;No -- go ahead a bit
270                 LDRB    R4,[R2]                 ;Get next character
271                 CMP     R4,#'P'                 ;Is it a 'P'?
272                 CMPNE   R4,#'p'                 ;Or a 'p'?
273                 ADDEQ   R2,R2,#1                ;Yes -- increment pointer
274                 MOVEQ   R0,#2                   ;...and set state to 2
275                 B       %00ptr__idles           ;break
276
277 21ptr__idles    CMP     R0,#2                   ;Are we in state 2?
278                 STREQB  R1,[R3],#1              ;Yes -- store the character
279                 B       %00ptr__idles           ;break
280
281                 ; --- case ',' ---
282
283 30ptr__idles    CMP     R1,#','                 ;Is it a ,?
284                 BNE     %40ptr__idles           ;No -- try next case
285                 CMP     R0,#2                   ;Are we in state 2?
286                 MOVEQ   R4,#0                   ;Yes -- get the NULL byte
287                 STREQB  R4,[R3],#1              ;... store it at end of name
288                 CMPNE   R0,#3                   ;Or state 3?
289                 CMPNE   R0,#4                   ;Or state 4?
290                 ADDEQ   R0,R0,#1                ;If any, increment the state
291                 B       %00ptr__idles           ;break
292
293                 ; --- default ---
294
295 40ptr__idles    CMP     R0,#1                   ;Are we in state 1?
296                 MOVEQ   R0,#0                   ;Yes -- put it in state 0
297                 BEQ     %00ptr__idles           ;break
298                 CMP     R0,#2                   ;State 2?
299                 STREQB  R1,[R3],#1              ;Yes -- store the character
300                 BEQ     %00ptr__idles           ;break
301                 CMP     R0,#3                   ;Are we in state 3?
302                 CMPNE   R0,#4                   ;Or 4?
303                 BNE     %00ptr__idles           ;No -- break
304                 CMP     R1,#'0'                 ;Is it less than '0'
305                 BLT     %00ptr__idles           ;Yes -- break
306                 CMP     R1,#'9'                 ;Is it greater than '9'
307                 BGT     %00ptr__idles           ;Yes -- break
308                 SUB     R1,R1,#'0'              ;Turn it into a number
309                 MOV     R4,#10                  ;A useful number
310                 CMP     R0,#3                   ;Are we reading x?
311                 MLAEQ   R5,R4,R5,R1             ;Yes -- calculate new x
312                 MLANE   R6,R4,R6,R1             ;No -- calculate new y
313                 B       %00ptr__idles           ;break
314
315                 ; --- We have finished parsing the string ---
316
317 70ptr__idles    CMP     R0,#1                   ;Is the state > 1?
318                 BLE     %80ptr__idles           ;No -- try default case
319                 ADD     R0,R11,#20              ;Point to sprite name
320                 MOV     R1,R5                   ;The x value
321                 MOV     R2,R6                   ;The y value
322                 BL      ptr_setShape            ;Set the pointer shape
323                 LDR     R14,ptr__flags          ;Get the new flags
324                 BIC     R14,R14,#ptr__USERSET   ;The user didn't set it
325                 STR     R14,ptr__flags          ;Store them again
326                 LDMFD   R13!,{R0-R7,PC}^        ;Return
327
328                 ; --- If the button type was writable, use caret_ptr ---
329
330 80ptr__idles    CMP     R7,#14                  ;Writable?
331                 CMPNE   R7,#15
332                 BNE     %90ptr__idles           ;Return
333                 ADR     R0,ptr__caretPtr        ;The sprite name
334                 MOV     R1,#4                   ;X offset
335                 MOV     R2,#5                   ;Y Offset
336                 BL      ptr_setShape            ;Set the pointer shape
337                 LDR     R14,ptr__flags          ;Get the new flags
338                 BIC     R14,R14,#ptr__USERSET   ;The user didn't set it
339                 STR     R14,ptr__flags          ;Store them again
340                 LDMFD   R13!,{R0-R7,PC}^        ;Return
341
342                 ; --- Return to the user ---
343
344 90ptr__idles    BL      ptr_resetShape          ;Reset the pointer
345                 LDMFD   R13!,{R0-R7,PC}^        ;...and return
346
347                 LTORG
348
349 ; --- ptr__postFilter ---
350 ;
351 ; On entry:     R0 == event code returned
352 ;               R1 == pointer to block returned
353 ;               R12 == pointer to my workspace
354 ;
355 ; On exit:      --
356 ;
357 ; Use:          Called as a post-filter to trap pointer entering/leaving
358 ;               events, so that idles may be added for pointer
359 ;               changing.
360
361 ptr__postFilter ROUT
362
363                 ; --- Ensure that we want this event ---
364
365                 CMP     R0,#4                   ;Pointer leaving?
366                 BEQ     %50ptr__postFilter      ;Yes -- handle that
367                 CMPNE   R0,#5                   ;Or entering?
368                 MOVNES  PC,R14                  ;Neither, return now
369
370                 ; --- Pointer is entering one of tasks windows ---
371
372                 STMFD   R13!,{R0-R3,R14}        ;Stack some registers
373                 MOV     R0,#2                   ;Call it this frequently
374                 ADR     R1,ptr__idles           ;Call this on idle events
375                 MOV     R2,#0                   ;Our user handle
376                 MOV     R3,R12                  ;Put our workspace in R12
377                 BL      idle_handler            ;Add the idle handler
378                 MOV     R0,#-1                  ;Set up previous icon number
379                 STR     R0,ptr__oldIcon         ;...to a non positive value
380                 LDMFD   R13!,{R0-R3,PC}^        ;Return to caller
381
382                 ; --- Pointer is leaving a window ---
383
384 50              STMFD   R13!,{R0-R3,R14}        ;Stack some registers
385                 MOV     R0,#2                   ;Call it this frequently
386                 ADR     R1,ptr__idles           ;Call this on idle events
387                 MOV     R2,#0                   ;Our user handle
388                 MOV     R3,R12                  ;Put our workspace in R12
389                 BL      idle_removeHandler      ;Remove the handler routine
390                 LDR     R14,ptr__flags          ;Load my flags word
391                 TST     R14,#ptr__USERSET       ;Is it the user's pointer?
392                 BLEQ    ptr_resetShape          ;No -- clear pointer shape
393                 LDMFD   R13!,{R0-R3,PC}^        ;And return to caller
394
395                 LTORG
396
397 ptr__caretPtr   DCB     "ptr_caret",0
398
399 ;----- Caret blinking -------------------------------------------------------
400
401 ; --- ptr__doCaret ---
402 ;
403 ; On entry:     R0 == flags word
404 ;               R1 == pointer to block to use
405 ;
406 ; On exit:      --
407 ;
408 ; Use:          Turn the caret on or off, according to the relevent bit
409 ;               in the flags word.
410
411 ptr__doCaret    ROUT
412
413                 MOV     R5,R0                   ;Remember flags word
414                 SWI     Wimp_GetCaretPosition   ;Get the caret position
415                 LDR     R0,[R1,#0]              ;Window handle
416                 LDR     R2,[R1,#8]              ;X offset
417                 LDR     R3,[R1,#12]             ;Y offset
418                 LDR     R4,[R1,#16]             ;Caret height and flags
419
420                 ; --- Set or clear the 'invisible' bit ---
421
422                 TST     R5,#ptr__ON             ;Turn the caret on?
423                 ORREQ   R4,R4,#1<<25            ;No, set the 'invisible' bit
424                 BICNE   R4,R4,#1<<25            ;No, clear 'invisible' bit
425
426                 ; --- Set the caret position ---
427
428                 LDR     R5,[R1,#20]             ;Index into string
429                 LDR     R1,[R1,#4]              ;Icon handle
430
431                 SWI     Wimp_SetCaretPosition   ;Put back invisible caret
432
433                 MOVS    PC,R14                  ;Return to caller
434
435                 LTORG
436
437 ; --- ptr__blinkCaret ---
438 ;
439 ; On entry:     R12 == workspace pointer
440 ;
441 ; On exit:      --
442 ;
443 ; Use:          Called by an alarm to flash the caret.
444
445 ptr__blinkCaret ROUT
446
447                 STMFD   R13!,{R0-R5,R14}        ;Stack some registers
448
449                 ; --- Do I own the task the carets in? ---
450
451                 MOV     R1,R11                  ;Point to scratchpad
452                 SWI     Wimp_GetCaretPosition   ;Get the caret position
453                 LDR     R2,[R1,#0]              ;Get window handle
454                 CMP     R2,#-1                  ;Is it in a window?
455                 BEQ     %00                     ;No -- set up alarm, return
456
457                 ; --- Send a acknowledgement message around ---
458
459                 MOV     R0,#20                  ;Message size
460                 STR     R0,[R1,#0]              ;Store in message block
461                 MOV     R0,#0                   ;Your ref
462                 STR     R0,[R1,#0]              ;Store in message block
463                 MOV     R0,#19                  ;Send message_acknowlegde
464                 SWI     Wimp_SendMessage        ;Send the message
465
466                 ; --- My task handle is now in R2 ---
467
468                 BL      wimp_taskHandle         ;Get the actual task handle
469                 CMP     R0,R2                   ;Do we own caret?
470                 BNE     %00                     ;No -- set up alarm, return
471
472                 ; --- Mess about withe my flags, and blink caret ---
473
474                 LDR     R0,ptr__flags           ;Get my flags word
475                 TST     R0,#ptr__ON             ;Is the caret on?
476                 BICNE   R0,R0,#ptr__ON          ;The caret is now off
477                 ORREQ   R0,R0,#ptr__ON          ;The caret is now on
478                 STR     R0,ptr__flags           ;Store flags back
479
480                 BL      ptr__doCaret            ;Blink the caret
481
482                 ; --- Prepare another alarm ---
483
484 00              BL      ptr__setUpAlarm         ;Prepare to flash again
485
486                 ; --- And return to caller ---
487
488                 LDMFD   R13!,{R0-R5,PC}^        ;Stack some registers
489
490                 LTORG
491
492 ; --- ptr__setUpAlarm ---
493 ;
494 ; On entry:     --
495 ;
496 ; On exit:      --
497 ;
498 ; Use:          Sets up an alarm to blink the caret
499
500 ptr__setUpAlarm ROUT
501
502                 STMFD   R13!,{R14}              ;Stack return address
503                 SWI     OS_ReadMonotonicTime    ;Get the current time
504                 ADD     R0,R0,#25               ;Add 1/25 of a second
505                 ADR     R1,ptr__blinkCaret      ;Call this routine
506                 ADR     R2,ptr__setUpAlarm      ;My private handle
507                 MOV     R3,R12                  ;Pass this for R12
508                 BL      idle_setAlarm           ;Set up the alarm
509                 LDMFD   R13!,{PC}               ;Return to caller
510
511                 LTORG
512
513 ; --- ptr_blinkOn ---
514 ;
515 ; On entry:     --
516 ;
517 ; On exit:      --
518 ;
519 ; Use:          Makes the caret blink while it is in a window owned by your
520 ;               application.
521
522                 EXPORT  ptr_blinkOn
523 ptr_blinkOn     ROUT
524
525                 STMFD   R13!,{R0-R3,R12,R14}    ;Stack some registers
526                 WSPACE  ptr__wSpace             ;Point to my workspace
527
528                 ; --- Turn on caret blinking ---
529
530                 LDR     R14,ptr__flags          ;Get my flags
531                 TST     R14,#ptr__BLINKING      ;Is blinking on?
532                 LDMNEFD R13!,{R0-R3,R12,PC}^    ;Yes -- return
533
534                 ORR     R14,R14,#ptr__BLINKING  ;Set the 'is blinking' bit
535                 STR     R14,ptr__flags          ;Store the flags word
536
537                 BL      ptr__setUpAlarm         ;Set up the blinking alarm
538
539                 ; --- Return to client ---
540
541                 LDMFD   R13!,{R0-R3,R12,PC}^    ;And return
542
543                 LTORG
544
545 ; --- ptr_blinkOff ---
546 ;
547 ; On entry:     --
548 ;
549 ; On exit:      --
550 ;
551 ; Use:          Turns the caret blinking off.
552
553                 EXPORT  ptr_blinkOff
554 ptr_blinkOff    ROUT
555
556                 STMFD   R13!,{R0-R5,R12,R14}    ;Stack some registers
557                 WSPACE  ptr__wSpace             ;Point to my workspace
558
559                 ; --- Is blinking already off? ---
560
561                 LDR     R14,ptr__flags          ;Get my flags
562                 TST     R14,#ptr__BLINKING      ;Is blinking on?
563                 LDMEQFD R13!,{R0-R5,R12,PC}^    ;Yes -- return
564
565                 BIC     R14,R14,#ptr__BLINKING  ;Clear the 'is blinking' bit
566                 STR     R14,ptr__flags          ;Store the flags word
567
568                 ; --- Remove any blink alarms already set up ---
569
570                 ADR     R0,ptr__setUpAlarm      ;My private handle
571                 BL      idle_removeAllAlarms    ;Remove all alarms I own
572
573                 ; --- Update my flags appropriately ---
574
575                 LDR     R0,ptr__flags           ;Get my flags word
576                 ORR     R0,R0,#ptr__ON          ;Caret is on
577                 STR     R0,ptr__flags           ;Store the flags back
578                 MOV     R1,R11                  ;Point to scratchpad
579                 BL      ptr__doCaret            ;Turn the caret off
580
581                 ; --- Return to client ---
582
583                 LDMFD   R13!,{R0-R5,R12,PC}^    ;And return
584
585                 LTORG
586
587 ;----- Initialisation -------------------------------------------------------
588
589 ; --- ptr_init ---
590 ;
591 ; On entry:     --
592 ;
593 ; On exit:      --
594 ;
595 ; Use:          Initialises the ptr system.
596
597                 EXPORT  ptr_init
598 ptr_init        ROUT
599
600                 STMFD   R13!,{R0,R1,R12,R14}    ;Stack some registers
601                 WSPACE  ptr__wSpace             ;Get my workspace
602
603                 ; --- Are we already initialised? ---
604
605                 LDR     R0,ptr__flags           ;Get my flags
606                 TST     R0,#ptr__INITED         ;Are we initialised?
607                 LDMNEFD R13!,{R0,R9,PC}^        ;Yes -- return
608
609                 ORR     R0,R0,#ptr__INITED+ptr__ON ;Set flags
610                 STR     R0,ptr__flags           ;And store them back
611
612                 ; --- Ensure that the event system is initialised ---
613
614                 BL      event_init
615
616                 ; --- And set up a post-filter for pointer changing ---
617
618                 ADR     R0,ptr__postFilter      ;Address of routine to call
619                 MOV     R1,R12                  ;Call with my workspace
620                 BL      event_postFilter        ;And add to the post filters
621
622                 ; --- Set up exit handler ---
623
624                 BL      except_init             ;Make sure except is awake
625                 ADR     R0,ptr_resetShape       ;Make pointer normal on exit
626                 MOV     R1,R12                  ;Pass workspace in R12
627                 BL      except_atExit           ;Register the routine
628
629                 ; --- That's it now ---
630
631                 LDMFD   R13!,{R0,R1,R12,PC}^    ;Return
632
633                 LTORG
634
635 ptr__wSpace     DCD     0                       ;My workspace pointer
636
637 ;----- Workspace ------------------------------------------------------------
638
639                 ^       0,R12
640 ptr__wStart     #       0
641
642 ptr__flags      #       4                       ;Flags
643
644 ptr__INITED     EQU     (1<<0)                  ;I've been initialised
645 ptr__BLINKING   EQU     (1<<1)                  ;Caret blinking is on
646 ptr__ON         EQU     (1<<2)                  ;Caret is on
647 ptr__NOTDEFAULT EQU     (1<<3)                  ;We're not using default ptr
648 ptr__USERSET    EQU     (1<<4)                  ;The user set the pointer
649
650 ptr__oldIcon    #       4                       ;Icon we were previously over
651
652 ptr__wSize      EQU     {VAR}-ptr__wStart
653
654                 AREA    |Sapphire$$LibData|,CODE,READONLY
655
656                 DCD     ptr__wSize              ;Workspace size
657                 DCD     ptr__wSpace             ;Workspace pointer
658                 DCD     40                      ;Scratchpad size
659                 DCD     ptr_init                ;Initialisation code
660
661 ;----- That's all, folks ----------------------------------------------------
662
663                 END