4 ; Event handling routines (TMA)
6 ; © 1994-1998 Straylight
9 ;----- Licensing note -------------------------------------------------------
11 ; This file is part of Straylight's Sapphire library.
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)
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.
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.
27 ;----- Standard header ------------------------------------------------------
32 ;----- External dependencies ------------------------------------------------
38 ;----- Macros ---------------------------------------------------------------
52 counter SETA counter+1
60 ;----- Main code ------------------------------------------------------------
62 AREA |Sapphire$$Code|,CODE,READONLY
65 ; --- event__addToList ---
67 ; On entry: R0 == pointer to routine to call
68 ; R1 == R12 value to call routine
69 ; R2 == pointer to list head to use
71 ; On exit: R0-R1 preserved, unless V set (when R0 points to error)
73 ; Use: Adds a rountine to the given list. Later added
74 ; routines are called first
79 STMFD R13!,{R0-R1,R14} ;Stack some registers
81 ; --- Allocate a block ---
83 MOV R0,#list__size ;Size to allocate
84 BL sub_alloc ;Allocate the block
85 BVS %01 ;Branch ahead if error
87 ; --- Fill the block in ---
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
93 LDMFD R13,{R1,R2} ;Get parameters
94 STMIB R0,{R1,R2} ;Store them in the block
96 ; --- And return to user ---
98 LDMFD R13!,{R0-R1,R14} ;Load back link
99 BICS PC,R14,#V_flag ;Return without error
101 ; --- Barf if an error occured ---
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
109 ; --- event_preFilter ---
111 ; On entry: R0 == pointer to routine to call
112 ; R1 == R12 value to call routine
114 ; On exit: May return an error
116 ; Use: Adds a routine to the pre-filter list. Later added
117 ; routines are called first.
119 EXPORT event_preFilter
122 STMFD R13!,{R2,R10,R14} ;Save some registers
124 ; --- Be careful not to alter flags ---
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
133 ; --- event_fakeHandler ---
135 ; On entry: R0 == pointer to routine to call
136 ; R1 == R12 value to call routine
138 ; On exit: May return an error
140 ; Use: Adds a routine to the fake handler list. Later added
141 ; routines are called first.
143 EXPORT event_fakeHandler
147 STMFD R13!,{R2,R10,R14} ;Save some registers
149 ; --- Be careful not to alter flags ---
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
158 ; --- event_postFilter ---
160 ; On entry: R0 == pointer to routine to call
161 ; R1 == R12 value to call routine
163 ; On exit: May return an error
165 ; Use: Adds a routine to the post-poll list. Later added
166 ; routines are called first.
168 EXPORT event_postFilter
172 STMFD R13!,{R2,R10,R14} ;Save some registers
174 ; --- Be careful not to alter flags ---
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
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
190 ; On exit: R0 == reason code
191 ; CS if the event was claimed, CC otherwise
193 ; Use: This call perform a Wimp_Poll, and dispatches events to
194 ; interested parties.
199 STMFD R13!,{R8-R10,R12,R14}
200 WSPACE event__wSpace,R10 ;Find my workspace
202 ; --- Run through the pre poll list here ---
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
213 ; -- If carry is set, jump the Wimp_Poll & fake list ---
215 BCS %19event_poll ;Jump ahead
217 ; --- If we are faking, do fake like things ---
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
228 ; --- Do the Wimp_Poll ---
230 ; Make sure the hourglass goes off during the poll, though
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
238 CMP R2,#0 ;Are we getting NULLs ASAP
239 SWIEQ Wimp_Poll ;Yes -- Normal Poll
240 SWINE Wimp_PollIdle ;No -- PollIdle
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
248 ; --- Copy over the event ---
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
255 ; --- Deal with fake events ---
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
269 13event_poll STR R8,event__fakePos ;Store the fake position
271 ; --- Store the last event away ---
273 19event_poll ADR R14,event__lastCode ;Point to last event cache
274 STMIA R14,{R0,R1} ;Save the information away
276 ; --- Scan the post-filters ---
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
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
297 ; On exit: R0 == last event code received from Wimp_Poll
298 ; R1 == pointer to accompanying event data
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.
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
324 ; Use: Initialises the event system.
329 STMFD R13!,{R0-R3,R10,R14} ;Stack some registers
330 WSPACE event__wSpace,R10 ;Get my workspace
332 ; --- Are we already initialised? ---
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
338 ORR R0,R0,#event__INITED ;Set initialised flag
339 STR R0,event__flags ;And store them back
341 ; --- Clear rest of workspace ---
343 MOV R0,#0 ;Zero some registers
347 STMIB R10,{R0-R3} ;Clear pre/post list
349 ; --- Initialise suballoc ---
351 BL sub_init ;Sub, short for SUBmarine
353 ; --- That's it now ---
355 LDMFD R13!,{R0-R3,R10,PC}^ ;Return
359 event__wSpace DCD 0 ;My workspace pointer
361 ;----- Workspace ------------------------------------------------------------
366 event__flags # 4 ;Flags
368 event__INITED EQU (1<<0) ;I've been initialised
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
375 event__lastCode # 4 ;The last event reason code
376 event__lastData # 4 ;The last event data pointer
378 event__prevR0 # 4 ;R0 for real event
379 event__buffer # 256 ;The event received
381 event__wSize EQU {VAR}-event__wStart
383 ; --- Pre/Post list structure ---
392 AREA |Sapphire$$LibData|,CODE,READONLY
394 DCD event__wSize ;Workspace size
395 DCD event__wSpace ;Workspace pointer
396 DCD 0 ;Scratchpad size
397 DCD event_init ;Initialisation code
399 ;----- That's all, folks ----------------------------------------------------