Initial revision
[ssr] / StraySrc / Libraries / Sapphire / dbx / s / numWrite
1 ;
2 ; dbx.numWrite.s
3 ;
4 ; Numeric writable icons (MDW)
5 ;
6 ; © 1994 Straylight
7 ;
8
9 ;----- Standard header ------------------------------------------------------
10
11 GET libs:header
12 GET libs:swis
13
14 ;----- External dependencies ------------------------------------------------
15
16 GET sapphire:dbox
17 GET sapphire:keyMap
18 GET sapphire:string
19
20 GET sapphire:dbx.dbx
21 GET sapphire:dbx._dbxMacs
22
23 ;----- Main code ------------------------------------------------------------
24
25 AREA |Sapphire$$Code|,CODE,READONLY
26
27 ; --- numWrite ---
28 ;
29 ; Control data: +0 == minimum value
30 ; +4 == maximum value
31 ; +8
32 ;
33 ; Workspace: +0
34 ;
35 ; Flags: --
36 ;
37 ; Use: Control type for numeric writable icons.
38
39 EXPORT numWrite
40 numWrite ROUT
41
42 DBXWS 0 ;No need for workspace
43 DCD dbxMask_key ;Interested in keypresses
44
45 STMFD R13!,{R0-R7,R14} ;Save lots of registers
46 MOV R6,R2 ;Keep the new character safe
47
48 MOV R0,R10 ;And the dialogue box handle
49 BL dbox_getField ;Read the current contents
50 MOV R7,R2 ;Keep this pointer
51
52 ; --- Find out where the caret is ---
53
54 SUB R13,R13,#24 ;Make space for caret block
55 MOV R1,R13 ;Point at this block
56 SWI Wimp_GetCaretPosition ;Find where the caret is
57 LDR R5,[R13,#20] ;Load the icon index
58
59 ; --- Find out if this keypress is interesting ---
60
61 CMP R5,#0 ;Is the cursor at the start?
62 LDREQB R14,[R7,#0] ;Yes -- get the first byte
63 CMPEQ R14,#'-' ;Is it a minus sign?
64 BEQ %50numWrite ;Yes -- disallow it then
65
66 SUB R14,R6,#'0' ;Convert keypress to digit
67 CMP R14,#10 ;Is it a proper digit?
68 BCC %10numWrite ;Yes -- deal with it then
69 SUB R14,R6,#key_k0 ;Try again with keypad
70 CMP R14,#10 ;Is it a proper digit?
71 SUBCC R6,R6,#key_k0-'0' ;Yes -- convert to ASCII
72 BCC %10numWrite ;Yes -- deal with it then
73 CMP R6,#'-' ;Is is a `-' sign?
74 CMPNE R6,#key_kMinus ;Or the one on the keypad?
75 MOVEQ R6,#'-' ;Either -- make it a `-'
76 BNE %50numWrite ;No -- ignore it then
77 LDR R3,[R9,#0] ;Load the minimum value
78 CMP R3,#0 ;Does it allow negative nos?
79 BGE %50numWrite ;No -- ignore it then
80 CMP R5,#0 ;Is the cursor at the start?
81 BNE %50numWrite ;No -- ignore it then
82
83 ; --- We've got a character to insert ---
84
85 10numWrite MOV R2,R7 ;Point at the icon's text
86 MOV R7,#0 ;An initial index
87 20numWrite CMP R7,R5 ;Is this the caret position?
88 MOVEQ R14,R6 ;Yes -- insert my char
89 LDRNEB R14,[R2],#1 ;Otherwise load from icon
90 STRB R14,[R11,R7] ;Save in position
91 CMP R14,#32 ;Is there more to go?
92 ADDGE R7,R7,#1 ;Increment the index
93 BGE %20numWrite ;Yes -- go round again
94 SUB R7,R7,#1 ;This is the original length
95
96 ; --- Fill the icon in nicely ---
97
98 MOV R2,R11 ;Point to my nice new string
99 BL numWrite__read ;Convert it to an integer
100 MOV R6,R2 ;Take a copy of this value
101 LDR R1,[R13,#28] ;Load the icon number
102 LDMIA R9,{R3,R4} ;Load the boundary values
103 SUB R4,R4,R3 ;Get the range size
104 SUB R14,R2,R3 ;Subtract the bottom end
105 CMP R14,R4 ;Is the value in range?
106 MOVLS R0,R10 ;Yes -- get dialogue handle
107 MOVLS R2,R11 ;Point at the string I made
108 BLLS dbox_setField ;And just write the string
109 BLHI numWrite__set ;Otherwise set the value
110 MOVHI R6,R2 ;If changed, copy value
111 BL dbx_sendEvent ;Send the user an event
112
113 ; --- Move the caret on ---
114
115 MOV R0,R10 ;Get the dialogue handle
116 BL dbox_getField ;Find the text address
117 MOV R0,R2 ;Point to the buffer
118 BL str_len ;Find the string length
119 SUBS R14,R0,R7 ;Find the length difference
120 BEQ %40numWrite ;No movement -- forget it
121 ADD R5,R5,R14 ;Move caret position on 1
122 CMP R5,R0 ;Is the caret in range?
123 LDMLSIA R13,{R0-R4} ;Load rest of caret state
124 SWILS Wimp_SetCaretPosition ;Set this as the new pos
125
126 ; --- Pass an event to the user ---
127
128 MOV R0,#numWrite_event ;Get the event number
129 MOV R2,#numWrite_change ;The value has been changed
130 MOV R3,R6 ;Pass the value in R3
131 BL dbx_sendEvent ;Pass the event on
132
133 40numWrite ADD R13,R13,#24 ;Restore the stack now
134 LDMFD R13!,{R0-R7,R14} ;Unstack the registers
135 ORRS PC,R14,#C_flag ;I used the character
136
137 ; --- Handle a weird character ---
138
139 50numWrite ADD R13,R13,#24 ;Restore the stack
140
141 ; --- Make sure it's an arrow key ---
142
143 TST R6,#&100 ;Is the top bit set?
144 BEQ %90numWrite ;No -- just return then
145 BIC R6,R6,#&130 ;Ignore modifier bits
146 CMP R6,#key_Tab-&100 ;Is it tab?
147 CMPNE R6,#key_sTab-&100 ;Or is it shift-tab?
148 CMPNE R6,#key_Up-&100 ;Or any of the cursor keys?
149 CMPNE R6,#key_Down-&100
150 CMPNE R6,#key_cUp-&100 ;Or maybe with control
151 CMPNE R6,#key_cDown-&100
152 BNE %90numWrite ;No -- just return then
153
154 LDR R1,[R13,#4] ;Load the icon number
155 MOV R0,R10 ;Get my dialogue handle
156 BL numWrite_read ;Read the current value
157 BL numWrite__set ;Set this as the new value
158 MOV R0,#numWrite_event ;Get my event code
159 MOV R3,R2 ;Pass value in R3
160 MOV R2,#numWrite_move ;The cursor has moved
161 BL dbx_sendEvent ;Send the user an event
162
163 90numWrite LDMFD R13!,{R0-R7,R14} ;Unstack the registers
164 BICS PC,R14,#C_flag ;Let someone else have it
165
166 LTORG
167
168 ; --- numWrite_set ---
169 ;
170 ; On entry: R0 == dialogue box handle
171 ; R1 == icon number within dialogue
172 ; R2 == value to set in the icon
173 ;
174 ; On exit: R2 == value actually set
175 ;
176 ; Use: Writes the specified numeric value into the given writable
177 ; icon. The icon must be a dbx control with numWrite type
178 ; for this to work.
179
180 EXPORT numWrite_set
181 numWrite_set ROUT
182
183 STMFD R13!,{R0,R1,R8-R10,R14} ;Save some registers
184 MOV R10,R0 ;Keep the dialogue handle
185 BL dbx_findData ;Look up all the dbx info
186 BL numWrite__set ;Do the actual work
187 LDMFD R13!,{R0,R1,R8-R10,PC}^ ;Return to caller
188
189 LTORG
190
191 ; --- numWrite__set ---
192 ;
193 ; On entry: R1 == icon handle to set it in
194 ; R2 == value to set
195 ; R9 == pointer to minimum and maximum values
196 ; R10 == dialogue box handle
197 ;
198 ; On exit: R2 == actual value set
199 ;
200 ; Use: Forces the given value between the limits for the icon
201 ; and writes it into the specified icon.
202
203 numWrite__set STMFD R13!,{R0-R2,R14} ;Save some registers
204
205 ; --- Force the value in range ---
206
207 LDMIA R9,{R0,R1} ;Load min and max values
208 CMP R2,R0 ;Is it big enough?
209 MOVLT R2,R0 ;No -- make it bigger then
210 CMP R2,R1 ;Is it small enough?
211 MOVGT R2,R1 ;No -- make it smaller then
212 STR R2,[R13,#8] ;Return this modified value
213
214 ; --- Translate it into a string ---
215
216 MOV R0,R2 ;Get value in R0 now
217 MOV R1,R11 ;Build string in scratchpad
218 MOV R2,#256 ;Specify the scratchpad size
219 SWI OS_ConvertInteger4 ;Convert it to a string
220
221 ; --- Write it into the icon ---
222
223 MOV R2,R0 ;Point at my nice new string
224 LDR R1,[R13,#4] ;Load the icon handle back
225 MOV R0,R10 ;Get the dialogue handle
226 BL dbox_setField ;And write it into the icon
227 LDMFD R13!,{R0-R2,PC}^ ;Return to caller
228
229 LTORG
230
231 ; --- numWrite_read ---
232 ;
233 ; On entry: R0 == dialogue box handle
234 ; R1 == icon handle
235 ;
236 ; On exit: CC if icon contains a valid integer, and
237 ; R2 == value shown in the icon
238 ; else CS and
239 ; R2 == 0
240 ;
241 ; Use: Reads the numeric value within the icon specifed.
242
243 EXPORT numWrite_read
244 numWrite_read ROUT
245
246 STMFD R13!,{R14} ;Save the link register
247 BL dbox_getField ;Find the icon string
248 BL numWrite__read ;Convert it to an integer
249 LDMFD R13!,{PC} ;Return it and the flags
250
251 LTORG
252
253 ; --- numWrite__read ---
254 ;
255 ; On entry: R2 == pointer to a string
256 ;
257 ; On exit: R2 == integer represented by string and CC or 0 and CS
258 ;
259 ; Use: Converts a string showing a decimal integer to the value
260 ; it represents.
261
262 numWrite__read ROUT
263
264 STMFD R13!,{R0,R1,R14}
265
266 ; --- Set up some initial values ---
267
268 MOV R0,R2 ;Point to the string start
269 MOV R1,#0 ;Not found any digits yet
270 MOV R2,#0 ;A good accumulator
271
272 ; --- Check for a leading sign ---
273
274 LDRB R14,[R0],#1 ;Load a byte from the string
275 CMP R14,#'-' ;Is it a `-' sign?
276 ORREQ R1,R1,#1 ;Set the `negative' bit
277 LDREQB R14,[R0],#1 ;Yes -- load another byte
278
279 ; --- Now read bytes from the string ---
280 ;
281 ; We stop as soon as we find a character which isn't a
282 ; digit.
283
284 10 SUB R14,R14,#'0' ;Convert to an integer
285 CMP R14,#10 ;Is it in range?
286 BCS %20numWrite__read ;No -- that's it then
287 TST R1,#1 ;Is the number negative?
288 ADD R2,R2,R2,LSL #2 ;Multiply by 5
289 ADDEQ R2,R14,R2,LSL #1 ;If +ve, double and add new
290 RSBNE R2,R14,R2,LSL #1 ;Otherwise, subtract it
291 ORR R1,R1,#2 ;Say we read something good
292 LDRB R14,[R0],#1 ;Load a new byte
293 B %10numWrite__read ;Go round the loop again
294
295 ; --- Return the value ---
296
297 20 TST R1,#2 ;Was the number valid?
298 LDMFD R13!,{R0,R1,R14} ;Restore the registers
299 ORREQS PC,R14,#C_flag ;No -- set C as error warning
300 BICNES PC,R14,#C_flag ;Otherwise clear it
301
302 LTORG
303
304 ; --- numWrite_bump ---
305 ;
306 ; On entry: R0 == dialogue box handle
307 ; R1 == icon handle
308 ; R2 == increment to apply to it
309 ;
310 ; On exit: R2 == updated value in the icon
311 ;
312 ; Use: Adjusts the value in a writable icon by a given increment.
313
314 EXPORT numWrite_bump
315 numWrite_bump ROUT
316
317 STMFD R13!,{R0,R1,R3,R14} ;Save some registers
318 MOV R3,R2 ;Look after the increment
319 BL numWrite_read ;Read the current value
320 ADDCC R2,R2,R3 ;If valid, apply increment
321 BL numWrite_set ;And write the value back
322 LDMFD R13!,{R0,R1,R3,PC}^ ;Return to caller
323
324 LTORG
325
326 ;----- Constants ------------------------------------------------------------
327
328 numWrite_event EQU &80000004 ;R1 == icon number changed
329 ;R2 == subreason code
330 ;R3 == new value of icon
331
332 numWrite_change EQU 0 ;Subreason -- number changed
333 numWrite_move EQU 1 ;Subreason -- cursor moved
334
335 ;----- That's all, folks ----------------------------------------------------
336
337 END