Initial revision
[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