Initial revision
[ssr] / StraySrc / Libraries / Sapphire / dbx / s / dbx
1 ;
2 ; dbx.dbx.s
3 ;
4 ; Managing dialogue box control types (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:msgs
18 GET sapphire:screen
19
20 ;----- Main code ------------------------------------------------------------
21
22 AREA |Sapphire$$Code|,CODE,READONLY
23
24 ; --- dbx_declare ---
25 ;
26 ; On entry: R0 == dialogue box handle from dbox
27 ; R1 == pointer to dialogue box definition block
28 ;
29 ; On exit: --
30 ;
31 ; Use: Declares a dialogue box to be dbx-managed, and declares the
32 ; control types of all its controls.
33
34 EXPORT dbx_declare
35 dbx_declare ROUT
36
37 STMFD R13!,{R0-R2,R10,R14} ;Save some registers
38 MOV R10,R0 ;Get dialogue handle
39
40 ; --- Sort out what needs doing ---
41
42 LDR R14,[R10,#dbx__defn] ;Is there a dbx definition?
43 CMP R14,#0 ;If so, this isn't zero
44 BEQ %10dbx_declare ;No -- skip onwards
45
46 ; --- Shut down the existing controls ---
47
48 MOV R2,R1 ;Keep the control block
49 MOV R0,#dbxEvent_lifeCycle ;Get the lifecycle code
50 LDR R14,[R10,#dbox__flags] ;Load the flags word
51 TST R14,#dbFlag__open ;Is the box open right now?
52 MOVNE R1,#dblc_close ;Tell controls it's closed
53 BLNE dbx__broadcast ;Send the message
54 MOV R1,#dblc_destroy ;Tell controls to shut down
55 BL dbx__broadcast ;Send the message
56 STR R2,[R10,#dbx__defn] ;Save the new control block
57 B %50dbx_declare ;And skip ahead
58
59 ; --- Set up first dbx controls ---
60
61 10dbx_declare STR R1,[R10,#dbx__defn] ;Store the definition pointer
62 ADD R14,R10,#dbox__proc ;Point to the event proc
63 LDMIA R14,{R0-R2} ;Load all the information
64 ADD R14,R10,#dbx__proc ;Point to my bit of data
65 STMIA R14,{R0-R2} ;Save the old handler away
66
67 ; --- Now set up the dbx handler ---
68
69 ADR R14,dbx__events ;Point to my event handler
70 STR R14,[R0,#dbox__proc] ;Save this as the new proc
71 STR R10,[R0,#dbox__R10] ;Pass dbox handle in R10
72
73 ; --- Send initialise messages ---
74
75 50dbx_declare MOV R0,#dbxEvent_lifeCycle ;Get the event code
76 MOV R1,#dblc_create ;Send creation notice
77 BL dbx__broadcast ;Send the message
78 LDR R14,[R10,#dbox__flags] ;Load the flags word
79 TST R14,#dbFlag__open ;Is the dialogue open?
80 MOVNE R1,#dblc_open ;Inform controls it's open
81 BLNE dbx__broadcast ;And send the message
82
83 ; --- Done (at last) ---
84
85 LDMFD R13!,{R0-R2,R10,PC}^ ;Return to caller
86
87 LTORG
88
89 ; --- dbx_sendEvent ---
90 ;
91 ; On entry: R0 == event code to send
92 ; R1-R7 == depend on the event code
93 ; R10 == dialogue box handle
94 ;
95 ; On exit: C flag as set by event handler
96 ;
97 ; Use: Sends an event to the specified dialogue box. This is
98 ; intended to be used by control handlers, hence the unusual
99 ; placing of the dialogue handle in R10.
100
101 EXPORT dbx_sendEvent
102 dbx_sendEvent ROUT
103
104 STMFD R13!,{R8-R10,R12,R14} ;Save some registers
105 MOV R9,R10 ;Pass dialogue handle in R9
106 LDR R14,[R10,#dbx__defn] ;Is this dialogue box dbx'ed?
107 CMP R14,#0 ;Yes -- then this isn't 0
108 ADDEQ R14,R10,#dbox__proc ;No -- point to real proc
109 ADDNE R14,R10,#dbx__proc ;Yes -- point to saved proc
110 LDMIA R14,{R8,R10,R12} ;Load the proc bitties
111 ADDS R0,R0,#0 ;Clear the carry flag
112 TEQ R8,#0 ;Is there a handler?
113 MOV R14,PC ;Set up return address
114 MOVNE PC,R8 ;Call the handler then
115 LDMFD R13!,{R8-R10,R12,R14} ;Load the registers I saved
116 ORRCSS PC,R14,#C_flag ;If C set, set C on exit
117 BICCCS PC,R14,#C_flag ;If C clear, clear C on exit
118
119 LTORG
120
121 ; --- dbx__events ---
122 ;
123 ; On entry: R0 == event code
124 ; R1-R7 == depend on event type
125 ; R10 == dialogue box handle
126 ;
127 ; On exit: --
128 ;
129 ; Use: Handles events for a dbx-managed dialogue box.
130
131 dbx__events ROUT
132
133 ; --- Make sure it's an interesting event ---
134
135 CMP R0,#dbEvent_redraw ;Is it a redraw event?
136 BEQ dbx__redraw ;Handle redraws specially
137
138 CMP R0,#0 ;Is icon handle in R0?
139 BGE %10dbx__events ;Yes -- handle cleverly
140
141 CMP R0,#dbEvent_help ;Test events with icon in R1
142 CMPNE R0,#dbEvent_save
143 CMPNE R0,#dbEvent_load
144 CMPNE R0,#dbEvent_menu
145 BEQ %20dbx__events ;If any of them, handle it
146
147 CMP R0,#dbEvent_drag ;And now ones with icon in R2
148 CMPNE R0,#dbEvent_key
149 BEQ %30dbx__events
150
151 CMP R0,#dbEvent_lifeCycle ;Is it a lifecycle broadcast?
152 BEQ %40dbx__events
153
154 ; --- Don't recognise the event ---
155 ;
156 ; So we'd better pass it to the original dbox handle
157
158 B dbx_sendEvent ;This handles everything!
159
160 ; --- Handle mouse click events ---
161
162 10dbx__events STMFD R13!,{R0-R2,R14} ;Save some registers away
163 MOV R2,R1 ;Get mouse button state
164 MOV R1,R0 ;Get the icon clicked
165 MOV R0,#dbxEvent_click ;Give control a click event
166 BL dbx__ctrlEvent ;Send it to the control
167 LDMFD R13!,{R0-R2,R14} ;Restore all the registers
168 B %80dbx__events ;Tidy up things with C flag
169
170 ; --- Handle events with icon handle in R1 ---
171
172 20dbx__events STMFD R13!,{R0-R5,R14} ;Save a load of registers
173 CMP R0,#dbEvent_menu ;Is this a menu click event?
174 MOVEQ R0,#dbxEvent_click ;Yes -- then give a click
175 MOVEQ R2,#2 ;And set the `menu' bit
176
177 MOV R5,#dbxDrop_load ;Assume event is a load
178 CMP R0,#dbEvent_save ;Is this a save event?
179 MOVEQ R5,#dbxDrop_save ;Yes -- it's a save instead
180 CMPNE R0,#dbEvent_load ;Or maybe it's a load event
181 MOVEQ R0,#dbxEvent_drop ;It's a file dropped event
182
183 CMP R0,#dbEvent_help ;In that case, it's a help?
184 MOVEQ R0,#dbxEvent_help ;Yes -- set up that event
185
186 BL dbx__ctrlEvent ;Send it to the control
187 LDMFD R13!,{R0-R5,R14} ;Restore a load of registers
188 B %80dbx__events ;And tidy everything up
189
190 ; --- And now handle the oddities with handles in R2 ---
191 ;
192 ; Both of these work just the same -- swap R2 and R1 over,
193 ; load event code into R0 and dispatch the event
194
195 30dbx__events STMFD R13!,{R0-R2,R14} ;Save some registers away
196 EOR R1,R1,R2 ;The standard swap-in-three
197 EOR R2,R1,R2 ;R2 == old_R1 now
198 EOR R1,R1,R2 ;R1 == old_R2 now. Done!
199 CMP R0,#dbEvent_drag ;Was it a drag event?
200 MOVEQ R0,#dbxEvent_click ;Yes -- deliver a click
201 MOVNE R0,#dbxEvent_key ;No -- deliver a keypress
202 BL dbx__ctrlEvent ;Send it to the control
203 LDMFD R13!,{R0-R2,R14} ;Restore the registers
204 B %80dbx__events ;And tidy everything up
205
206 ; --- Handle lifecycle changes ---
207
208 40dbx__events STMFD R13!,{R0,R14} ;Save some registers
209 MOV R0,#dbxEvent_lifeCycle ;Get the event code
210 BL dbx__broadcast ;Send the message out
211 LDMFD R13!,{R0,R14} ;Restore registers
212 B %80dbx__events ;And tidy everything up
213
214 ; --- Now handle the standard aftermath ---
215 ;
216 ; If the control didn't like it, we pass the whole event on
217 ; to the user dialogue box handler.
218
219 80dbx__events BCC dbx_sendEvent ;Send event to user if nec.
220 ORRS PC,R14,#C_flag ;Otherwise, we claim it
221
222 LTORG
223
224 ; --- dbx_findData ---
225 ;
226 ; On entry: R0 == icon handle
227 ; R10 == dialogue box handle
228 ;
229 ; On exit: If found, CS and
230 ; R8 == pointer to writable control data
231 ; R9 == pointer to static control data
232 ; else CC and
233 ; R8, R9 corrupted
234 ;
235 ; Use: Allows a control to find its data when called by client
236 ; code.
237
238 EXPORT dbx_findData
239 dbx_findData ROUT
240
241 STMFD R13!,{R4-R7,R14} ;Save some registers
242 LDR R9,[R10,#dbx__defn] ;Find the dialogue def block
243 10dbx_findData LDMIA R9,{R4-R8} ;Load all the information
244 CMP R4,#-1 ;Is the icon handle -1?
245 BEQ %80dbx_findData ;Yes -- icon handle not found
246 CMP R1,R4 ;Is this a match we have?
247 ADDNE R9,R9,R7 ;No -- add in the block size
248 BNE %10dbx_findData ;And loop around again
249
250 ; --- Find control's workspace if necessary ---
251 ;
252 ; If the user has not supplied control writable data and
253 ; it wants some, an address exception is created.
254
255 ADD R9,R9,#16 ;Point past this block header
256 TST R6,#dbxFlag_dataR10 :OR: dbxFlag_dataR12
257 MOVEQ R8,#&80000000 ;Address exception if wanted
258 BEQ %15dbx_findData ;No data -- skip onwards
259
260 ADD R9,R9,#4 ;Skip past data offset word
261 TST R6,#dbxFlag_dataR10 ;Does he want R10-relative?
262 LDRNE R14,[R10,#dbx__R10] ;Yes -- load user's R10 value
263 LDREQ R14,[R10,#dbx__R12] ;No -- load user's R12 value
264 ADD R8,R14,R8 ;Add in loaded offset nicely
265
266 15dbx_findData LDMFD R13!,{R4-R7,R14} ;Unstack registers
267 ORRS PC,R14,#C_flag ;Say we found it OK
268
269 80dbx_findData LDMFD R13!,{R4-R7,R14} ;Unstack registers
270 BICS PC,R14,#C_flag ;Say we couldn't find it
271
272 LTORG
273
274 ; --- dbx__ctrlEvent ---
275 ;
276 ; On entry: R0 == dbx event code type
277 ; R1 == icon handle to dispatch to
278 ; R2-R7 == depend on the event code
279 ; R10 == dialogue box handle
280 ;
281 ; On exit: Registers preserved, C set if control claimed the event
282 ;
283 ; Use: Sends an event to a control, setting up all the registers
284 ; etc. appropriately.
285
286 dbx__ctrlEvent ROUT
287
288 STMFD R13!,{R4-R9,R14} ;Save masses of registers
289 LDR R9,[R10,#dbx__defn] ;Find the dialogue def block
290 MOV R4,R13 ;Point to stacked registers
291 00 LDMIA R9,{R4-R8} ;Load all the information
292 CMP R4,#-1 ;Is the icon handle -1?
293 BEQ %80dbx__ctrlEvent ;Yes -- icon handle not found
294 CMP R1,R4 ;Is this a match we have?
295 ADDNE R9,R9,R7 ;No -- add in the block size
296 BNE %b00 ;And loop around again
297 BL dbx__deliver ;Deliver the event
298 LDMFD R13!,{R4-R9,R14} ;Unstack registers
299 ORRCSS PC,R14,#C_flag ;And return with C set
300 BICCCS PC,R14,#C_flag ;Or not, appropriately
301
302 80 LDMFD R13!,{R4-R9,R14} ;Unstack registers
303 BICS PC,R14,#C_flag ;Event was not claimed
304
305 LTORG
306
307 ; --- dbx__deliver ---
308 ;
309 ; On entry: R0 == dbx event code to deliver
310 ; R1-R3 == arguments specific to the event
311 ; R4 == pointer to more arguments for event (R4-R7)
312 ; R5 == (untransformed) pointer to event code
313 ; R6 == dbx control flags
314 ; R7 == size of control block
315 ; R8 == pointer to control writable data
316 ; R9 == address of control information
317 ; R10 == dialogue handle
318 ;
319 ; On exit: Registers preserved, C set if control claimed the event
320 ;
321 ; Use: Delivers an event to a control.
322
323 dbx__deliver ROUT
324
325 STMFD R13!,{R4-R9,R12,R14} ;Save some registers
326
327 ; --- Check that the control is interested ---
328
329 BL dbx__xform ;Translate R5 nicely
330 LDMIA R5,{R7,R12,R14} ;Load control R12 and flags
331 CMP R7,#0 ;Is there an address?
332 LDRNE R7,[R7,#0] ;Load workspace offset
333 LDRNE R12,[R11,-R12] ;Load workspace base address
334 ADDNE R12,R12,R7 ;And work out workspace
335 MOV R7,#1 ;To shift the bit around
336 TST R14,R7,LSL R0 ;Check event's mask bit
337 BEQ %80dbx__deliver ;Bit is clear -- ignore event
338
339 ; --- Find control's workspace if necessary ---
340 ;
341 ; If the user has not supplied control writable data and
342 ; it wants some, an address exception is created.
343
344 ADD R9,R9,#16 ;Point past this block header
345 TST R6,#dbxFlag_dataR10 :OR: dbxFlag_dataR12
346 MOVEQ R8,#&80000000 ;Address exception if wanted
347 BEQ %15dbx__deliver ;No data -- skip onwards
348
349 ADD R9,R9,#4 ;Skip past data offset word
350 TST R6,#dbxFlag_dataR10 ;Does he want R10-relative?
351 LDRNE R14,[R10,#dbx__R10] ;Yes -- load user's R10 value
352 LDREQ R14,[R10,#dbx__R12] ;No -- load user's R12 value
353 ADD R8,R14,R8 ;Add in loaded offset nicely
354
355 ; --- Writable data pointer is set up then ---
356
357 15dbx__deliver LDMIA R4,{R4-R7} ;Fetch saved registers
358 MOV R14,PC ;Set up return address nicely
359 ADD PC,R5,#12 ;Call the control's code
360
361 LDMFD R13!,{R4-R9,R12,R14} ;Restore all the registers
362 ORRCSS PC,R14,#C_flag ;If C set, set C on return
363 BICCCS PC,R14,#C_flag ;Otherwise clear C on return
364
365 ; --- We couldn't find a suitable control ---
366
367 80dbx__deliver LDMFD R13!,{R4-R9,R12,R14} ;Restore all the registers
368 BICS PC,R14,#C_flag ;Clear C -- event ignored
369
370 LTORG
371
372
373 ; --- dbx__broadcast ---
374 ;
375 ; On entry: R0 == dbx event code
376 ; R1-R7 depend on the event code
377 ; R10 == dialogue box handle
378 ;
379 ; On exit: ---
380 ;
381 ; Use: Sends an event to all controls in a dialogue box.
382
383 dbx__broadcast ROUT
384
385 STMFD R13!,{R4-R9,R14} ;Save some registers
386 LDR R9,[R10,#dbx__defn] ;Find the control definition
387 MOV R4,R13 ;Point to stacked arguments
388 00 LDMIA R9,{R4-R8} ;Load information from block
389 CMP R4,#-1 ;Is icon number bogus?
390 LDMEQFD R13!,{R4-R9,PC}^ ;Yes -- then return
391 BL dbx__deliver ;Deliver the event
392 ADD R9,R9,R7 ;Move on to next event
393 B %b00 ;And keep on looping
394
395 LTORG
396
397 ; --- dbx__xform ---
398 ;
399 ; On entry: R5 == pointer to a dbx control
400 ;
401 ; On exit: R5 possibly modified
402 ;
403 ; Use: Translates R5 to point to a dbx control block. The problem
404 ; is dynamic linking: R5 might actually point to a branch
405 ; to the real control. So we spot that here and hack around
406 ; the problem.
407
408 dbx__xform ROUT
409
410 STMFD R13!,{R14} ;Save a register
411 LDR R14,[R5,#0] ;Load the pointer out
412 CMP R14,#&80000000 ;Is the pointer out of range?
413 BICCS R14,R14,#&FF000000 ;Clear instruction bits
414 ADDCS R14,R14,#2 ;Account for pipeline
415 ADDCS R5,R5,R14,LSL #2 ;And work out the address
416 LDMFD R13!,{PC}^ ;And return to caller
417
418 LTORG
419
420 ; --- dbx__redraw ---
421 ;
422 ; On entry: R0 == dbEvent_redraw
423 ; R1 == pointer to redraw rectangle block
424 ; R2 == x coordinate of window origin on screen
425 ; R3 == y coordinate of window origin on screen
426 ; R10 == dialogue box handle
427 ;
428 ; On exit: Registers preserved, C clear on exit unless user claimed
429 ; the redraw event.
430 ;
431 ; Use: Handles a redraw event for a dbx-controlled dialogue box.
432 ; We go through all the controls in the block and test which
433 ; ones want redraw events. For each one, we set the graphics
434 ; rectangle to the intersection of the icon bounding box and
435 ; the redraw rectangle, load the screen position of the icon
436 ; and pass the control handler a redraw event.
437
438 dbx__redraw ROUT
439
440 STMFD R13!,{R14} ;Save return address
441 BL dbx_sendEvent ;Let the user do some redraw
442 LDMCSFD R13!,{PC} ;If it was claimed, return
443 STMFD R13!,{R0-R9,R12} ;Save some more registers
444
445 ; --- Set up some standard registers ---
446
447 MOV R6,R2 ;Look after the origin coords
448 MOV R7,R3 ;Both x and y -- we need 'em
449 ADD R5,R1,#28 ;Point to redraw rectangle
450
451 LDR R0,[R10,#dbx__defn] ;Find the control definitions
452
453 ; --- Now loop through the controls ---
454
455 10dbx__redraw LDMIA R0,{R1-R4,R8} ;Load the control information
456 CMP R1,#-1 ;Is this the end of the list?
457 BEQ %90dbx__redraw ;Yes -- return to caller
458
459 ; --- Check if the control likes redraw events ---
460
461 LDR R14,[R2,#0] ;Load the value out
462 CMP R14,#&80000000 ;Is it out of range?
463 BICCS R14,R14,#&ff000000 ;Yes -- clear instruction
464 ADDCS R14,R14,#2 ;Compensate for pipeline
465 ADDCS R2,R2,R14,LSL #2 ;And work out real address
466 LDMIA R2,{R9,R12,R14} ;Load control R12 and flags
467 CMP R9,#0 ;Is there an address?
468 LDRNE R9,[R9,#0] ;Load workspace offset
469 LDRNE R12,[R11,-R12] ;Load workspace base
470 ADDNE R12,R12,R9 ;Work out workspace address
471 TST R14,#1<<dbxEvent_redraw ;Is the mask bit set for 'em?
472 ADDEQ R0,R0,R4 ;No -- move to next one
473 BEQ %10dbx__redraw ;And loop back round again
474
475 ; --- It does -- spring into action then ---
476
477 ADD R9,R0,#16 ;Point past this block header
478 TST R3,#dbxFlag_dataR10 :OR: dbxFlag_dataR12
479 MOVEQ R8,#&80000000 ;Address exception if wanted
480 BEQ %15dbx__redraw ;No data -- skip onwards
481
482 ADD R9,R9,#4 ;Skip past data offset word
483 TST R3,#dbxFlag_dataR10 ;Does he want R10-relative?
484 LDRNE R14,[R10,#dbx__R10] ;Yes -- load user's R10 value
485 LDREQ R14,[R10,#dbx__R12] ;No -- load user's R12 value
486 ADD R8,R14,R8 ;Add in loaded offset nicely
487
488 ; --- Registers R8 onwards are all set up then ---
489
490 15dbx__redraw STMFD R13!,{R0,R2-R5} ;Save some more registers
491 LDR R0,[R10,#dbox__defn] ;Load the window def pointer
492 ADD R0,R0,#88 ;Point to the first icon
493 ADD R0,R0,R1,LSL #5 ;Point to R1th icon
494 LDMIA R0,{R2-R5,R14} ;Load icon coordinates
495 ADD R2,R2,R6 ;Convert them to screen ones
496 ADD R3,R3,R7
497 ADD R4,R4,R6
498 ADD R5,R5,R7
499
500 ; --- Trim icon so all coords are inclusive ---
501
502 STMFD R13!,{R6-R10} ;Save some temp regs too
503 TST R14,#4 ;Does icon have a border?
504 BL screen_getInfo ;Get the current screen info
505 ADD R0,R0,#screen_dx ;Point to the pixel sizes
506 LDMIA R0,{R10,R14} ;Load the pixel sizes out
507 SUB R4,R4,R10 ;Chop off the extra x pixel
508 SUB R5,R5,R14 ;Chop off the y one too
509 SUBNE R4,R4,R10 ;If border, take off an...
510 SUBNE R5,R5,R14 ;... extra pixel all the...
511 ADDNE R2,R2,R10 ;... way round to stop...
512 ADDNE R3,R3,R14 ;... nasty flickery effects
513
514 ; --- Now load the graphics window and compare ---
515
516 LDR R6,[R13,#36] ;Load the rectangle pointer
517 LDMIA R6,{R6-R9} ;Load the rectangle coords
518 SUB R8,R8,R10 ;Trim these coordinates too
519 SUB R9,R9,R14
520 CMP R2,R8 ;Check they overlap
521 CMPLE R3,R9
522 CMPLE R6,R4
523 CMPLE R7,R5
524 BGT %70dbx__redraw ;And skip to the end
525
526 ; --- Now construct the intersection rectangle ---
527
528 STMFD R13!,{R6-R9} ;Save these coordinates away
529 CMP R6,R2
530 MOVLT R6,R2
531 CMP R7,R3
532 MOVLT R7,R3
533 CMP R8,R4
534 MOVGT R8,R4
535 CMP R9,R5
536 MOVGT R9,R5
537
538 ; --- Set this as the graphics rectangle ---
539
540 MOV R6,R6,LSL #8 ;Shift x0 up one byte
541 ORR R6,R6,#24 ;Set graphics rectangle code
542 ORR R6,R6,R7,LSL #24 ;Move in bottom byte of y0
543 MOV R7,R7,LSR #8 ;Get top byte of y0
544 ORR R7,R7,R8,LSL #8 ;Move in both bytes of x1
545 ORR R7,R7,R9,LSL #24 ;Move in bottom byte of y1
546 MOV R8,R9,LSR #8 ;Get top byte of y1
547 STMFD R13!,{R1,R6-R8} ;Save that lot on the stack
548 ADD R0,R13,#4 ;Point to VDU sequence
549 MOV R1,#9 ;Length of the sequence
550 SWI OS_WriteN ;Write them to the VDU
551 LDMFD R13!,{R1} ;Restore R1 from the stack
552 ADD R13,R13,#12 ;Reclaim stack from VDU op
553
554 ; --- Now call the control's event handler ---
555
556 ADD R14,R13,#24 ;Point to old saved registers
557 LDMIA R14!,{R8-R10} ;Restore arguments for event
558 LDR R6,[R13,#52] ;Load graphics window pointer
559 LDR R0,[R14,#4] ;Get the control handler ptr
560 ADD R0,R0,#12 ;Point to the handler code
561 STMFD R13!,{R0} ;Save it on the stack
562 MOV R0,#dbxEvent_redraw ;Give it a redraw event code
563 MOV R14,PC ;Set up the return address
564 LDMFD R13!,{PC} ;Call the routine nicely
565
566 ; --- Tidy everything up once more ---
567
568 LDMFD R13!,{R6-R9} ;Get the old graphics window
569 MOV R6,R6,LSL #8 ;Shift x0 up one byte
570 ORR R6,R6,#24 ;Set graphics rectangle code
571 ORR R6,R6,R7,LSL #24 ;Move in bottom byte of y0
572 MOV R7,R7,LSR #8 ;Get top byte of y0
573 ORR R7,R7,R8,LSL #8 ;Move in both bytes of x1
574 ORR R7,R7,R9,LSL #24 ;Move in bottom byte of y1
575 MOV R8,R9,LSR #8 ;Get top byte of y1
576 STMFD R13!,{R6-R8} ;Save that lot on the stack
577 MOV R0,R13 ;Point to VDU sequence
578 MOV R1,#9 ;Length of the sequence
579 SWI OS_WriteN ;Restore graphics window
580 ADD R13,R13,#12 ;Reclaim stack from VDU op
581
582 70dbx__redraw LDMFD R13!,{R6-R10} ;Restore main code's R6-R10
583 LDMFD R13!,{R0,R2-R5} ;Restore variables for loop
584 ADD R0,R0,R4 ;Move on to the next block
585 B %10dbx__redraw ;Go back to the main loop
586
587 ; --- Return to the caller ---
588
589 90dbx__redraw LDMFD R13!,{R0-R9,R12,R14} ;Restore a load of registers
590 BICS PC,R14,#C_flag ;Return without claiming
591
592 LTORG
593
594 ; --- dbx_controlBBox ---
595 ;
596 ; On entry: R0 == dialogue box handle
597 ; R1 == control icon number
598 ;
599 ; On exit: R0,R1 preserved
600 ; R2-R5 == inclusive screen coordinates of icon bounding box
601 ;
602 ; Use: Calculates the position *on the screen* of the given control
603 ; icon, and returns it to you as a set of four inclusive
604 ; coordinates (*not* inclusive-exclusve as the WIMP tends to
605 ; return to you)
606
607 EXPORT dbx_controlBBox
608 dbx_controlBBox ROUT
609
610 STMFD R13!,{R0,R1,R6,R7,R14} ;Save a load of registers
611 MOV R7,R0 ;Look after the dbox handle
612 LDR R0,[R0,#dbox__defn] ;Find the window definition
613 ADD R0,R0,#88 ;Find the first icon defn
614 ADD R0,R0,R1,LSL #5 ;Find the correct icon defn
615 LDMIA R0,{R2-R6} ;Load coordinates and flags
616 TST R6,#4 ;Does the icon have a border?
617
618 BL screen_getInfo ;Find info about the screen
619 ADD R0,R0,#screen_dx ;Point to the pixel sizes
620 LDMIA R0,{R0,R1} ;Load the pixel sizes
621
622 SUB R4,R4,R0 ;Get the inclusive coords
623 SUB R5,R5,R1
624 SUBNE R4,R4,R0 ;If border, move inwards
625 SUBNE R5,R5,R1
626 ADDNE R2,R2,R0
627 ADDNE R3,R3,R1
628
629 LDR R0,[R7,#dbox__window] ;Get the dbox's window handle
630 SUB R13,R13,#36 ;Make way for icon state blk
631 STR R0,[R13,#0] ;Save the window handle in it
632 MOV R1,R13 ;Point at the block
633 SWI Wimp_GetWindowState ;Get all the window info
634
635 LDR R6,[R1,#4] ;Get the min x coordinate
636 ADD R1,R1,#16 ;Point to the max y coord
637 LDMIA R1,{R0,R7,R14} ;Load the other coords I want
638 SUB R6,R6,R7 ;Get the x origin position
639 SUB R7,R0,R14 ;Get the y origin position
640
641 ADD R2,R2,R6 ;Convert icon posn to screen
642 ADD R3,R3,R7
643 ADD R4,R4,R6
644 ADD R5,R5,R7
645
646 ADD R13,R13,#36 ;Reclaim that stack I used
647 LDMFD R13!,{R0,R1,R6,R7,PC}^ ;Return to caller happy
648
649 LTORG
650
651 ; --- dbx_update ---
652 ;
653 ; On entry: R0 == dialogue box handle
654 ; R1 == icon number of control to update
655 ;
656 ; On exit: --
657 ;
658 ; Use: Redraws the specified control immediately. If the control
659 ; does not redraw itself, this call does nothing.
660
661 EXPORT dbx_update
662 dbx_update ROUT
663
664 STMFD R13!,{R2,R14} ;Save some registers
665 MOV R2,#dbxEvent_redraw ;Send a redraw event
666 BL dbx__update ;Perform the redraw
667 LDMFD R13!,{R2,PC}^ ;And return to caller
668
669 LTORG
670
671 ; --- dbx_qUpdate ---
672 ;
673 ; On entry: R0 == dialogue box handle
674 ; R1 == icon number of control to update
675 ;
676 ; On exit: --
677 ;
678 ; Use: Makes a control quickly update itself in whichever way it
679 ; needs to in order to be perfect again. It is anticipated
680 ; that this is used to update EORed areas of the control.
681
682 EXPORT dbx_qUpdate
683 dbx_qUpdate ROUT
684
685 STMFD R13!,{R2,R14} ;Save some registers
686 MOV R2,#dbxEvent_update ;Send an update event
687 BL dbx__update ;Perform the redraw
688 LDMFD R13!,{R2,PC}^ ;And return to caller
689
690 LTORG
691
692 ; --- dbx__update ---
693 ;
694 ; On entry: R0 == dialogue box handle
695 ; R1 == icon number of control to update
696 ; R2 == event to send to control
697 ;
698 ; On exit: --
699 ;
700 ; Use: Sends events to a control to perform an update. This is used
701 ; for dbx_update and for dbx_qUpdate.
702
703 dbx__update ROUT
704
705 STMFD R13!,{R0-R10,R12,R14} ;Save a large number of regs
706 MOV R10,R0 ;Look after the dbox handle
707
708 ; --- Try to find the control ---
709
710 LDR R9,[R10,#dbx__defn] ;Find the dialogue def block
711 10dbx__update LDMIA R9,{R4-R8} ;Load all the information
712 CMP R4,#-1 ;Is the icon handle -1?
713 BEQ %80dbx__update ;Yes -- icon handle not found
714 CMP R1,R4 ;Is this a match we have?
715 ADDNE R9,R9,R7 ;No -- add in the block size
716 BNE %10dbx__update ;And loop around again
717
718 ; --- We have found the control ---
719 ;
720 ; Check that it supports redraw events.
721
722 BL dbx__xform ;Translate the pointer
723 LDMIA R5,{R4,R12,R14} ;Load control R12 and flags
724 CMP R4,#0 ;Is there any workspace?
725 LDRNE R4,[R4,#0] ;Load workspace offset
726 LDRNE R12,[R11,-R12] ;Load workspace base
727 ADDNE R12,R12,R4 ;And work out workspace
728 MOV R4,#1 ;A value to shift with
729 TST R14,R4,LSL R2 ;Check it wants the event
730 BEQ %80dbx__update ;No -- skip to the end
731
732 ; --- Now find the control's workspace ---
733
734 ADD R9,R9,#16 ;Point past this block header
735 TST R6,#dbxFlag_dataR10 :OR: dbxFlag_dataR12
736 MOVEQ R8,#&80000000 ;Address exception if wanted
737 BEQ %15dbx__update ;No data -- skip onwards
738
739 ADD R9,R9,#4 ;Skip past data offset word
740 TST R6,#dbxFlag_dataR10 ;Does he want R10-relative?
741 LDRNE R14,[R10,#dbx__R10] ;Yes -- load user's R10 value
742 LDREQ R14,[R10,#dbx__R12] ;No -- load user's R12 value
743 ADD R8,R14,R8 ;Add in loaded offset nicely
744
745 ; --- Now we need to find the icon definition ---
746
747 15dbx__update ADD R5,R5,#12 ;Point to the control handler
748 STMFD R13!,{R5} ;Save control handler ptr
749 LDR R0,[R10,#dbox__defn] ;Load the window def pointer
750 ADD R0,R0,#88 ;Point to the first icon
751 ADD R0,R0,R1,LSL #5 ;Point to R1th icon
752 LDMIA R0,{R2-R6} ;Load icon coordinates
753 SUB R13,R13,#44 ;Make way for a redraw blk
754 LDR R14,[R10,#dbox__window] ;Get the dialogue's window
755 STR R14,[R13,#0] ;Store it in the block
756 STMIB R13,{R2-R5} ;Store icon coordinates too
757
758 ; --- Start the window update ---
759
760 MOV R1,R13 ;Point to the update block
761 SWI Wimp_UpdateWindow ;Give me a first rectangle
762 CMP R0,#0 ;Is there anything to do?
763 BEQ %70dbx__update ;No -- skip to loop bottom
764
765 ; --- Fix the icon bounding box to be inclusive ---
766
767 TST R6,#4 ;Does icon have a border?
768 BL screen_getInfo ;Get the screen information
769 ADD R0,R0,#screen_dx ;Point to the pixel sizes
770 LDMIA R0,{R6,R7} ;Get the pixel sizes
771 SUB R4,R4,R6 ;Chop off the extra x pixel
772 SUB R5,R5,R7 ;Chop off the y one too
773 SUBNE R4,R4,R6 ;If border, take off an...
774 SUBNE R5,R5,R7 ;... extra pixel all the...
775 ADDNE R2,R2,R6 ;... way round to stop...
776 ADDNE R3,R3,R7 ;... nasty flickery effects
777
778 ; --- Now translate the whole thing to window coords ---
779
780 LDR R6,[R1,#4] ;Get the window left position
781 ADD R0,R1,#16 ;Point to the top position
782 LDMIA R0,{R0,R7,R14} ;Load top, and scroll posns
783 SUB R6,R6,R7 ;Convert to find origin x
784 SUB R7,R0,R14 ;Convert to find origin y
785 ADD R2,R2,R6 ;Convert rectangle now
786 ADD R3,R3,R7
787 ADD R4,R4,R6
788 ADD R5,R5,R7
789 ADD R6,R13,#28 ;Load graphic window pointer
790
791 ; --- Now do the main update loop ---
792
793 20dbx__update LDR R1,[R13,#52] ;Load control's icon handle
794 LDR R0,[R13,#56] ;And the event which we send
795 MOV R14,PC ;Set up the return address
796 LDR PC,[R13,#44] ;Call the control routine
797 MOV R1,R13 ;Point to the update block
798 SWI Wimp_GetRectangle ;Get the next rectangle
799 CMP R0,#0 ;Are there any more left?
800 BNE %20dbx__update ;Yes -- loop round again
801
802 ; --- Tidy up the stack and registers ---
803
804 70dbx__update ADD R13,R13,#48 ;Restore all the stack
805
806 ; --- Return to caller ---
807
808 80dbx__update LDMFD R13!,{R0-R10,R12,PC}^ ;Return to caller at last
809
810 LTORG
811
812 ;----- Dialogue box blocks --------------------------------------------------
813
814 ^ 0
815
816 ; --- Information for dbox ---
817
818 dbox__window # 4 ;The real window handle
819 dbox__proc # 4 ;Pointer to event handler
820 dbox__R10 # 4 ;Magic handle for event proc
821 dbox__R12 # 4 ;Workspace for event proc
822 dbox__oldCaret # 24 ;Caret position to restore
823 dbox__defn # 4 ;Pointer to window template
824 dbox__template # 4 ;Pointer to original template
825 dbox__title # 4 ;Embedded title icon number
826 dbox__flags # 4 ;Various interesting flags
827
828 ; --- Information for dbx ---
829
830 dbx__proc # 4 ;Pointer to user event proc
831 dbx__R10 # 4 ;Object pointer for user proc
832 dbx__R12 # 4 ;Workspace for user proc
833 dbx__defn # 4 ;Pointer to control def block
834
835 dbox__blockSize # 0 ;Size of the above block
836
837 ; --- Flags ---
838
839 dbFlag__open EQU (1<<0) ;Borrowed from dbox
840
841 ;----- dbx dialogue definition ----------------------------------------------
842
843 ^ 0
844 dbx__icon # 4 ;Icon number of this control
845 dbx__control # 4 ;Pointer to control type
846 dbx__dbFlags # 4 ;Flags for the control
847 dbx__size # 4 ;Size of this control info
848 dbx__data # 4 ;(Optional) offset to data
849
850 dbxFlag_dataR10 EQU (1<<0) ;Has R10-relative data
851 dbxFlag_dataR12 EQU (1<<1) ;Has R12-relative data
852
853 ;----- dbx control definition -----------------------------------------------
854
855 ^ 0
856 dbx__ctrlR12 # 4 ;Workspace for control
857 dbx__ctrlFlags # 4 ;Flags mask for the control
858 dbx__handler # 4 ;The actual handler code
859
860 ;----- dbx event codes ------------------------------------------------------
861
862 ^ 0
863 dbxEvent_click # 1
864 dbxEvent_redraw # 1
865 dbxEvent_key # 1
866 dbxEvent_drop # 1
867 dbxEvent_help # 1
868 dbxEvent_update # 1
869 dbxEvent_lifeCycle # 1
870
871 ^ 0
872 dbxDrop_load # 1
873 dbxDrop_save # 1
874
875 ;----- That's all, folks ----------------------------------------------------
876
877 END