chiark / gitweb /
JPEG support and other fixes from Nick Clark
[ssr] / StraySrc / Libraries / Sapphire / s / event
1 ;
2 ; event.s
3 ;
4 ; Event handling routines (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:sapphire
35                 GET     sapphire:suballoc
36                 GET     sapphire:hour
37
38 ;----- Macros ---------------------------------------------------------------
39
40                 MACRO
41                 BUFCOPY
42
43                 LCLA    counter
44 counter         SETA    0
45
46                 STMFD   R13!,{R0-R6}
47
48         WHILE counter<8
49
50                 LDMIA   R9!,{R0-R6,R14}
51                 STMIA   R8!,{R0-R6,R14}
52 counter         SETA    counter+1
53
54         WEND
55
56                 LDMFD   R13!,{R0-R6}
57
58                 MEND
59
60 ;----- Main code ------------------------------------------------------------
61
62                 AREA    |Sapphire$$Code|,CODE,READONLY
63
64
65 ; --- event__addToList ---
66 ;
67 ; On entry:     R0 == pointer to routine to call
68 ;               R1 == R12 value to call routine
69 ;               R2 == pointer to list head to use
70 ;
71 ; On exit:      R0-R1 preserved, unless V set (when R0 points to error)
72 ;
73 ; Use:          Adds a rountine to the given list. Later added
74 ;               routines are called first
75
76 event__addToList
77                 ROUT
78
79                 STMFD   R13!,{R0-R1,R14}        ;Stack some registers
80
81                 ; --- Allocate a block ---
82
83                 MOV     R0,#list__size          ;Size to allocate
84                 BL      sub_alloc               ;Allocate the block
85                 BVS     %01                     ;Branch ahead if error
86
87                 ; --- Fill the block in ---
88
89                 LDR     R1,[R2]                 ;Get the list head
90                 STR     R1,[R0,#list__next]     ;Store in next field
91                 STR     R0,[R2]                 ;Store new block at head
92
93                 LDMFD   R13,{R1,R2}             ;Get parameters
94                 STMIB   R0,{R1,R2}              ;Store them in the block
95
96                 ; --- And return to user ---
97
98                 LDMFD   R13!,{R0-R1,R14}        ;Load back link
99                 BICS    PC,R14,#V_flag          ;Return without error
100
101                 ; --- Barf if an error occured ---
102
103 01              ADD     R13,R13,#4              ;Skip over R0
104                 LDMFD   R13!,{R1,R14}           ;Branch if error
105                 ORRS    PC,R14,#V_flag          ;Return with error
106
107                 LTORG
108
109 ; --- event_preFilter ---
110 ;
111 ; On entry:     R0 == pointer to routine to call
112 ;               R1 == R12 value to call routine
113 ;
114 ; On exit:      May return an error
115 ;
116 ; Use:          Adds a routine to the pre-filter list. Later added
117 ;               routines are called first.
118
119                 EXPORT  event_preFilter
120 event_preFilter ROUT
121
122                 STMFD   R13!,{R2,R10,R14}       ;Save some registers
123
124                 ; --- Be careful not to alter flags ---
125
126                 WSPACE  event__wSpace,R10       ;Get my workspace pointer
127                 ADR     R2,event__preList       ;Get the pre-list pointer
128                 BL      event__addToList        ;Add the routine to the list
129                 LDMFD   R13!,{R2,R10,PC}        ;Return cunningly
130
131                 LTORG
132
133 ; --- event_fakeHandler ---
134 ;
135 ; On entry:     R0 == pointer to routine to call
136 ;               R1 == R12 value to call routine
137 ;
138 ; On exit:      May return an error
139 ;
140 ; Use:          Adds a routine to the fake handler list. Later added
141 ;               routines are called first.
142
143                 EXPORT  event_fakeHandler
144 event_fakeHandler
145                 ROUT
146
147                 STMFD   R13!,{R2,R10,R14}       ;Save some registers
148
149                 ; --- Be careful not to alter flags ---
150
151                 WSPACE  event__wSpace,R10       ;Get my workspace pointer
152                 ADR     R2,event__fakeList      ;Get the fake-list pointer
153                 BL      event__addToList        ;Add the routine to the list
154                 LDMFD   R13!,{R2,R10,PC}        ;Return cunningly
155
156                 LTORG
157
158 ; --- event_postFilter ---
159 ;
160 ; On entry:     R0 == pointer to routine to call
161 ;               R1 == R12 value to call routine
162 ;
163 ; On exit:      May return an error
164 ;
165 ; Use:          Adds a routine to the post-poll list. Later added
166 ;               routines are called first.
167
168                 EXPORT  event_postFilter
169 event_postFilter
170                 ROUT
171
172                 STMFD   R13!,{R2,R10,R14}       ;Save some registers
173
174                 ; --- Be careful not to alter flags ---
175
176                 WSPACE  event__wSpace,R10       ;Get my workspace pointer
177                 ADR     R2,event__postList      ;Get the post-list pointer
178                 BL      event__addToList        ;Add the routine to the list
179                 LDMFD   R13!,{R2,R10,PC}        ;Return cunningly
180
181                 LTORG
182
183 ; --- event_poll ---
184 ;
185 ; On entry:     R0 == event mask and flags
186 ;               R1 == pointer to block to use
187 ;               R2 == earliest time to return with NULL event
188 ;               R3 == optional pointer to poll word
189 ;
190 ; On exit:      R0 == reason code
191 ;               CS if the event was claimed, CC otherwise
192 ;
193 ; Use:          This call perform a Wimp_Poll, and dispatches events to
194 ;               interested parties.
195
196                 EXPORT  event_poll
197 event_poll      ROUT
198
199                 STMFD   R13!,{R8-R10,R12,R14}
200                 WSPACE  event__wSpace,R10       ;Find my workspace
201
202                 ; --- Run through the pre poll list here ---
203
204                 ADDS    R0,R0,#0                ;Clear the carry flag
205                 LDR     R8,event__preList       ;Get pre-list pointer
206 00event_poll    TEQ     R8,#0                   ;Are we at the end
207                 BEQ     %05event_poll           ;Yes -- branch ahead
208                 LDMIA   R8,{R8,R9,R12}          ;Get list fields
209                 MOV     R14,PC                  ;Set up return address
210                 MOV     PC,R9                   ;Branch to client routine
211                 BCC     %00event_poll           ;Keep going through list
212
213                 ; -- If carry is set, jump the Wimp_Poll & fake list ---
214
215                 BCS     %19event_poll           ;Jump ahead
216
217                 ; --- If we are faking, do fake like things ---
218
219 05event_poll    LDR     R8,event__fakePos       ;Get the current fake pos
220                 CMP     R8,#-1                  ;Are there any waiting?
221                 BEQ     %10event_poll           ;No -- do the Wimp_Poll
222                 MOV     R8,R1                   ;Point to users buffer
223                 ADR     R9,event__buffer        ;Point to my buffer
224                 BUFCOPY                         ;Copy the event
225                 LDR     R0,event__prevR0        ;Get the event type
226                 B       %11event_poll           ;Continue with fakes
227
228                 ; --- Do the Wimp_Poll ---
229                 ;
230                 ; Make sure the hourglass goes off during the poll, though
231
232 10event_poll    SUB     R13,R13,#8              ;Make space for hourglass blk
233                 STMFD   R13!,{R0}               ;Save the event mask
234                 ADD     R0,R13,#4               ;Point to the block
235                 BL      hour_suspend            ;Turn the hourglass off a bit
236                 LDR     R0,[R13,#0]             ;Load the event mask again
237
238                 CMP     R2,#0                   ;Are we getting NULLs ASAP
239                 SWIEQ   Wimp_Poll               ;Yes -- Normal Poll
240                 SWINE   Wimp_PollIdle           ;No -- PollIdle
241
242                 STR     R0,[R13,#0]             ;Save the Wimp_Poll reason
243                 ADD     R0,R13,#4               ;Point to the block
244                 BL      hour_resume             ;Restore the hourglass state
245                 LDMFD   R13!,{R0}               ;Restore the reason code
246                 ADD     R13,R13,#8              ;And reclaim the stack space
247
248                 ; --- Copy over the event ---
249
250                 ADR     R8,event__buffer        ;Point to my buffer
251                 MOV     R9,R1                   ;Point to users buffer
252                 BUFCOPY                         ;Copy the event
253                 STR     R0,event__prevR0        ;Remember event type
254
255                 ; --- Deal with fake events ---
256
257 11event_poll    LDR     R8,event__fakePos       ;Get the fake list
258                 CMP     R8,#-1                  ;Is there one?
259                 LDREQ   R8,event__fakeList      ;Get fake list if !resuming
260                 ADDS    R0,R0,#0                ;Clear the carry flag
261 12event_poll    TEQ     R8,#0                   ;Is there a fake handler?
262                 MOVEQ   R8,#-1                  ;No more to do
263                 BEQ     %13event_poll           ;No -- Scan filters
264                 LDMIA   R8,{R8-R9,R12}          ;Get arguments
265                 MOV     R14,PC                  ;Set return point
266                 MOV     PC,R9                   ;Branch to handler
267                 BCC     %12event_poll           ;Keep trying
268
269 13event_poll    STR     R8,event__fakePos       ;Store the fake position
270
271                 ; --- Store the last event away ---
272
273 19event_poll    ADR     R14,event__lastCode     ;Point to last event cache
274                 STMIA   R14,{R0,R1}             ;Save the information away
275
276                 ; --- Scan the post-filters ---
277
278                 LDR     R8,event__postList      ;Get post-list pointer
279                 ADDS    R0,R0,#0                ;Clear carry
280 20event_poll    TEQ     R8,#0                   ;Are we at the end
281                 BEQ     %30event_poll           ;Yes -- branch ahead
282                 LDMIA   R8,{R8-R9,R12}          ;Get list fields
283                 MOV     R14,PC                  ;Set up return address
284                 MOV     PC,R9                   ;Branch to client routine
285                 BCC     %20event_poll           ;Keep going through list
286
287 30event_poll    LDMFD   R13!,{R8-R10,R12,R14}
288                 BICCCS  PC,R14,#C_flag          ;Clear C if C clear :-)
289                 ORRCSS  PC,R14,#C_flag          ;Set C if C set
290
291                 LTORG
292
293 ; --- event_last ---
294 ;
295 ; On entry:     --
296 ;
297 ; On exit:      R0 == last event code received from Wimp_Poll
298 ;               R1 == pointer to accompanying event data
299 ;
300 ; Use:          Allows you to read the full event information.  The event
301 ;               is the same one currently being or most recently dispatched
302 ;               to the postfilter list, i.e. fake events are also returned
303 ;               by this call.  If no event has yet been received, the return
304 ;               values are undefined.
305
306                 EXPORT  event_last
307 event_last      ROUT
308
309                 LDR     R0,event__wSpace        ;Load my workspace offset
310                 LDR     R1,sapph_workspace      ;Load workspace base
311                 ADD     R0,R1,R0                ;Find actual workspace addr
312                 ADD     R0,R0,#:INDEX: event__lastCode
313                 LDMIA   R0,{R0,R1}              ;Load the information
314                 MOVS    PC,R14                  ;Return to caller
315
316                 LTORG
317
318 ; --- event_init ---
319 ;
320 ; On entry:     --
321 ;
322 ; On exit:      --
323 ;
324 ; Use:          Initialises the event system.
325
326                 EXPORT  event_init
327 event_init      ROUT
328
329                 STMFD   R13!,{R0-R3,R10,R14}    ;Stack some registers
330                 WSPACE  event__wSpace,R10       ;Get my workspace
331
332                 ; --- Are we already initialised? ---
333
334                 LDR     R0,event__flags         ;Get my flags
335                 TST     R0,#event__INITED       ;Are we initialised?
336                 LDMNEFD R13!,{R0-R3,R10,PC}^    ;Yes -- return
337
338                 ORR     R0,R0,#event__INITED    ;Set initialised flag
339                 STR     R0,event__flags         ;And store them back
340
341                 ; --- Clear rest of workspace ---
342
343                 MOV     R0,#0                   ;Zero some registers
344                 MOV     R1,#0
345                 MOV     R2,#0
346                 MOV     R3,#-1
347                 STMIB   R10,{R0-R3}             ;Clear pre/post list
348
349                 ; --- Initialise suballoc ---
350
351                 BL      sub_init                ;Sub, short for SUBmarine
352
353                 ; --- That's it now ---
354
355                 LDMFD   R13!,{R0-R3,R10,PC}^    ;Return
356
357                 LTORG
358
359 event__wSpace   DCD     0                       ;My workspace pointer
360
361 ;----- Workspace ------------------------------------------------------------
362
363                 ^       0,R10
364 event__wStart   #       0
365
366 event__flags    #       4                       ;Flags
367
368 event__INITED   EQU     (1<<0)                  ;I've been initialised
369
370 event__preList  #       4                       ;Pre-Poll list
371 event__fakeList #       4                       ;Event-faking list
372 event__postList #       4                       ;Post-Poll list
373 event__fakePos  #       4                       ;The current fake position
374
375 event__lastCode #       4                       ;The last event reason code
376 event__lastData #       4                       ;The last event data pointer
377
378 event__prevR0   #       4                       ;R0 for real event
379 event__buffer   #       256                     ;The event received
380
381 event__wSize    EQU     {VAR}-event__wStart
382
383 ; --- Pre/Post list structure ---
384
385                 ^       0
386 list__next      #       4
387 list__proc      #       4
388 list__r12       #       4
389
390 list__size      #       0
391
392                 AREA    |Sapphire$$LibData|,CODE,READONLY
393
394                 DCD     event__wSize            ;Workspace size
395                 DCD     event__wSpace           ;Workspace pointer
396                 DCD     0                       ;Scratchpad size
397                 DCD     event_init              ;Initialisation code
398
399 ;----- That's all, folks ----------------------------------------------------
400
401                 END