chiark / gitweb /
JPEG support and other fixes from Nick Clark
[ssr] / StraySrc / Libraries / Sapphire / s / hour
1 ;
2 ; hour.s
3 ;
4 ; Handling of the hourglass (MDW)
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 ;----- Here is Wisdom -------------------------------------------------------;
28 ; The standard Hourglass system is OK but for one small problem: you can't
29 ; stop the thing and restart where you left off.  So, we put a wrapper round
30 ; it so that we can do this.  This involves keeping our own record of
31 ; exactly what's going on.
32 ;
33 ; This module is designed to be very small and unobtrusive, so you can have
34 ; dependencies on it all over without much hassle.  The only external
35 ; dependency is on except, and wimp includes that anyway, so it's not really
36 ; a great problem.
37
38 ;----- Standard header ------------------------------------------------------
39
40                 GET     libs:header
41                 GET     libs:swis
42
43 ;----- External dependencies ------------------------------------------------
44
45                 GET     sapphire:except
46                 GET     sapphire:sapphire
47
48 ;----- Main code ------------------------------------------------------------
49
50                 AREA    |Sapphire$$Code|,CODE,READONLY
51
52 ; --- hour_init ---
53 ;
54 ; On entry:     --
55 ;
56 ; On exit:      --
57 ;
58 ; Use:          Initialises the hour system, so it will display an hourglass
59 ;               when necessary.
60 ;
61 ;               Since this gets called at a random point during the Sapphire
62 ;               initialisation, and we can rely on Hourglass keeping its
63 ;               own count, the suggested way of handling everything properly
64 ;               is as follows:
65 ;
66 ;                               SWI     Hourglass_On
67 ;                               BL      sapphire_init
68 ;                               SWI     Hourglass_Off
69
70                 EXPORT  hour_init
71 hour_init       ROUT
72
73                 STMFD   R13!,{R12,R14}          ;Save some registers
74                 WSPACE  hour__wSpace            ;Locate my workspace address
75
76                 ; --- Make sure I haven't already done this ---
77
78                 LDR     R14,hour__flags         ;Find my flags word nicely
79                 TST     R14,#hFlag__inited      ;Am I initialised yet?
80                 LDMNEFD R13!,{R12,PC}^          ;Yes -- return right now
81
82                 ; --- Set up my workspace properly ---
83
84                 STMFD   R13!,{R0-R2}            ;Save some more registers
85                 MOV     R0,#hFlag__inited       ;Say I'm initialised
86                 MOV     R1,#0                   ;No Hourglass count yet
87                 MOV     R2,#255                 ;No other status stuff either
88                 STMIA   R12,{R0-R2}             ;Save the stuff in workspace
89
90                 ; --- Register my atexit handler ---
91
92                 BL      except_init             ;Make sure except is awake
93                 ADR     R0,hour__exit           ;Point to the handler
94                 MOV     R1,R12                  ;Pass my workspace along
95                 BL      except_atExit           ;Make sure I can tidy up
96
97                 LDMFD   R13!,{R0-R2,R12,PC}^    ;Return to caller
98
99                 LTORG
100
101 hour__wSpace    DCD     0
102
103 ; --- hour__exit ---
104 ;
105 ; On entry:     --
106 ;
107 ; On exit:      --
108 ;
109 ; Use:          Kills off the Hourglass if it's displaying when the program
110 ;               finally quits.
111
112 hour__exit      ROUT
113
114                 STMFD   R13!,{R14}              ;Store the return address
115                 LDR     R14,hour__count         ;Find my Hourglass counter
116                 CMP     R14,#0                  ;Is it not displaying?
117                 SWIGT   Hourglass_Off           ;No -- turn it off then
118                 LDMFD   R13!,{PC}^              ;Return to caller finally
119
120                 LTORG
121
122 ; --- hour_on ---
123 ;
124 ; On entry:     --
125 ;
126 ; On exit:      --
127 ;
128 ; Use:          Turns the Hourglass on only if it isn't on already.
129 ;               Otherwise its status is left as it was.
130
131                 EXPORT  hour_on
132 hour_on         ROUT
133
134                 STMFD   R13!,{R12,R14}          ;Save a couple of registers
135                 WSPACE  hour__wSpace            ;Load my workspace pointer
136                 LDR     R14,hour__count         ;Find my Hourglass counter
137                 ADD     R14,R14,#1              ;Bump the counter on one
138                 STR     R14,hour__count         ;Store it back again
139                 CMP     R14,#1                  ;Has it just been turned on?
140                 SWIEQ   Hourglass_On            ;Yes -- turn it on then
141                 LDMFD   R13!,{R12,PC}^          ;Return to caller finally
142
143                 LTORG
144
145 ; --- hour_off ---
146 ;
147 ; On entry:     --
148 ;
149 ; On exit:      --
150 ;
151 ; Use:          Turns the Hourglass off if it's only been turned on once.
152 ;               If the Hourglass gets turned off, all the information about
153 ;               it (percentage and LEDs) get forgotten.
154
155                 EXPORT  hour_off
156 hour_off        ROUT
157
158                 STMFD   R13!,{R12,R14}          ;Save some registers
159                 WSPACE  hour__wSpace            ;Load my workspace pointer
160                 LDR     R14,hour__count         ;Find my Hourglass counter
161                 SUBS    R14,R14,#1              ;Decrement it nicely
162                 MOVLT   R14,#0                  ;If negative, keep at zero
163                 STR     R14,hour__count         ;Store counter back anyway
164                 STRLE   R14,hour__percent       ;If turning off, zero percent
165                 SWILE   Hourglass_Off           ;and turn Hourglass off too
166                 LDMFD   R13!,{R12,PC}^          ;Return to caller
167
168                 LTORG
169
170 ; --- hour_percent ---
171 ;
172 ; On entry:     R0 == percentage value to display, or -1 to remove
173 ;
174 ; On exit:      --
175 ;
176 ; Use:          Attaches a percentage display to the Hourglass.
177
178                 EXPORT  hour_percent
179 hour_percent    ROUT
180
181                 STMFD   R13!,{R12,R14}          ;Save some registers away
182                 WSPACE  hour__wSpace            ;Find my workspace address
183                 LDR     R14,hour__count         ;Get the counter out
184                 CMP     R14,#0                  ;Has it been turned on yet?
185                 STRGTB  R0,hour__percent        ;Yes -- store the percentage
186                 SWIGT   Hourglass_Percentage    ;And display it properly
187                 LDMFD   R13!,{R12,PC}^          ;Return to caller
188
189                 LTORG
190
191 ; --- hour_leds ---
192 ;
193 ; On entry:     R0 == LED mask EOR value
194 ;               R1 == LED mask AND value
195 ;
196 ; On exit:      --
197 ;
198 ; Use:          Changes the Hourglass LED status.
199
200                 EXPORT  hour_leds
201 hour_leds       STMFD   R13!,{R0,R1,R12,R14}    ;Save some registers away
202                 WSPACE  hour__wSpace            ;Find my workspace address
203                 LDR     R14,hour__count         ;Get the counter out
204                 CMP     R14,#0                  ;Has it been turned on yet?
205                 LDMLEFD R13!,{R0,R1,R12,PC}^    ;No -- just return then
206                 LDR     R14,hour__leds          ;Get the current LED state
207                 AND     R14,R14,R1              ;Apply the AND mask to it
208                 EOR     R0,R14,R0               ;Apply the EOR mask to it
209                 LDR     R0,hour__leds           ;Store the status back again
210                 MOV     R1,#0                   ;Clear all LED bits
211                 SWI     Hourglass_LEDs          ;Now set the actual LEDs
212                 LDMFD   R13!,{R0,R1,R12,PC}^    ;Return to caller
213
214                 LTORG
215
216 ; --- hour_suspend ---
217 ;
218 ; On entry:     R0 == pointer to 2 word block to save status in
219 ;
220 ; On exit:      --
221 ;
222 ; Use:          Saves the Hourglass state in a block you've pointed at,
223 ;               and disables the Hourglass.  Useful if you want to do some
224 ;               user interaction without polling (e.g. an error box).
225
226                 EXPORT  hour_suspend
227 hour_suspend    ROUT
228
229                 STMFD   R13!,{R0-R2,R12,R14}    ;Save a bunch of registers
230                 WSPACE  hour__wSpace            ;Load my workspace address
231                 LDMIB   R12,{R1,R2}             ;Load the Hourglass state
232                 STMIA   R0,{R1,R2}              ;Save it in caller's block
233                 CMP     R1,#0                   ;Is the Hourglass on ATM?
234                 SWIGT   Hourglass_Off           ;Yes -- turn it off then
235                 MOV     R1,#0                   ;Zero the counter
236                 MOV     R2,#255                 ;And the other status bits
237                 STMIB   R12,{R1,R2}             ;Save over my old state
238                 LDMFD   R13!,{R0-R2,R12,PC}^    ;Return to caller nicely
239
240                 LTORG
241
242 ; --- hour_save ---
243 ;
244 ; On entry:     R0 == pointer to 2 word block to save status in
245 ;
246 ; On exit:      --
247 ;
248 ; Use:          Saves the current Hourglass status without altering it.
249
250                 EXPORT  hour_save
251 hour_save       ROUT
252
253                 STMFD   R13!,{R0-R2,R12,R14}    ;Save a bunch of registers
254                 WSPACE  hour__wSpace            ;Load my workspace address
255                 LDMIB   R12,{R1,R2}             ;Load the Hourglass state
256                 STMIA   R0,{R1,R2}              ;Save it in caller's block
257                 LDMFD   R13!,{R0-R2,R12,PC}^    ;Return to caller finally
258
259                 LTORG
260
261 ; --- hour_resume, hour_restore ---
262 ;
263 ; On entry:     R0 == pointer to 2 words filled by hour_suspend or hour_save
264 ;
265 ; On exit:      --
266 ;
267 ; Use:          Restores the Hourglass state to that saved away by one
268 ;               of the previous two calls.  This routine has two names.
269
270                 EXPORT  hour_resume
271                 EXPORT  hour_restore
272 hour_resume
273 hour_restore    ROUT
274
275                 STMFD   R13!,{R0,R1,R12,R14}    ;Save some registers away
276                 WSPACE  hour__wSpace            ;Load my workspace address
277                 LDR     R14,hour__count         ;Load the current counter
278
279                 ; --- Restore the workspace contents ---
280
281                 LDMIA   R0,{R0,R1}              ;Load the saved status
282                 CMP     R0,#0                   ;Is the Hourglass on?
283                 MOVLT   R0,#0                   ;If negative, restore to 0
284                 MOVLE   R1,#255                 ;If off, force percent off
285                 STMIB   R12,{R0,R1}             ;Save in my workspace
286
287                 ; --- Now restore the Hourglass onness ---
288
289                 MOVGT   R0,#1                   ;If now on, store as 1
290                 CMP     R14,#0                  ;Is the old state on?
291                 MOVLT   R14,#0                  ;Force result nonnegative
292                 MOVGT   R14,#1                  ;If was on, store as 1
293                 CMP     R0,R14                  ;Are the states the same?
294                 SWIGT   Hourglass_On            ;If now on, was off, enable
295                 SWILT   Hourglass_Off           ;If now off, was on, disable
296                 CMP     R0,#0                   ;Is it now off?
297                 LDMEQFD R13!,{R0,R1,R12,PC}^    ;Yes -- return to caller
298
299                 ; --- Now restore other Hourglass bits ---
300
301                 AND     R0,R1,#&FF              ;Get the percentage state
302                 SWI     Hourglass_Percentage    ;Send that to the Hourglass
303                 AND     R0,R1,#&FF00            ;Get the LED state too
304                 MOV     R0,R0,LSR #8            ;Shift down to bottom of R0
305                 MOV     R1,#0                   ;Don't leave old state there
306                 SWI     Hourglass_LEDs          ;And restore LED state
307                 LDMFD   R13!,{R0,R1,R12,PC}^    ;Return, we did everything
308
309                 LTORG
310
311 ;----- Workspace ------------------------------------------------------------
312
313                 ^       0,R12
314 hour__wStart    #       0
315
316 hour__flags     #       4                       ;A flags word (see later)
317 hour__count     #       4                       ;no(hour_on) - no(hour_off)
318 hour__percent   #       1                       ;Current percentage displayed
319 hour__leds      #       1                       ;Current LED status
320 hour__padding   #       2                       ;Pad size to word boundary
321
322 hour__wSize     EQU     {VAR}-hour__wStart
323
324 hFlag__inited   EQU     (1<<0)                  ;Am I initialised yet?
325
326                 AREA    |Sapphire$$LibData|,CODE,READONLY
327
328                 DCD     hour__wSize
329                 DCD     hour__wSpace
330                 DCD     0
331                 DCD     hour_init
332
333 ;----- That's all, folks ----------------------------------------------------
334
335                 END