Initial revision
[ssr] / StraySrc / Libraries / Sapphire / s / template
1 ;
2 ; template.s
3 ;
4 ; Load window template resources (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 ;----- Standard header ------------------------------------------------------
28
29 GET libs:header
30 GET libs:swis
31
32 ;----- External dependencies ------------------------------------------------
33
34 GET sapphire:alloc
35 GET sapphire:fastMove
36 GET sapphire:except
37 GET sapphire:mem
38 GET sapphire:msgs
39 GET sapphire:res
40 GET sapphire:resources
41 GET sapphire:resspr
42 GET sapphire:sapphire
43 GET sapphire:string
44
45 ;----- Main code ------------------------------------------------------------
46
47 AREA |Sapphire$$Code|,CODE,READONLY
48
49 ; --- tpl__find ---
50 ;
51 ; On entry: R0 == pointer to name to find
52 ;
53 ; On exit: CS if template found in list, and
54 ; R0 == pointer to template block (internal format)
55 ; else CC if in shared resource
56 ; R0 == pointer to embedded template definition
57 ; May return an error
58 ;
59 ; Use: Finds a named template in the list.
60
61 tpl__find ROUT
62
63 ORRS R14,R14,#C_flag ;Set C initially
64 STMFD R13!,{R1,R2,R12,R14} ;Stack some registers
65 WSPACE template_wspace ;Find my workspace
66 LDR R2,template_list ;Find the list head
67
68 ; --- Go through the list trying to find one ---
69
70 00 CMP R2,#0 ;Is this the list end?
71 BEQ %10tpl__find ;Yes -- return the error
72 ADD R1,R2,#tlist_name ;Find this template's name
73 BL str_icmp ;Compare the names
74 LDRNE R2,[R2,#tlist_next] ;If no match, get next one...
75 BNE %b00 ;And go round again
76
77 ; --- We found a match!!! ---
78
79 MOV R0,R2 ;Point to the template
80 LDMFD R13!,{R1,R2,R12,R14} ;Unstack some registers
81 BICS PC,R14,#V_flag ;Return with no error
82
83 ; --- No match -- try shared resource ---
84
85 10tpl__find MOV R1,R0 ;Point to the template name
86 MOV R0,#rsType_template ;Search for template resource
87 BL resources_find ;Try to find the resource
88 LDMCSFD R13!,{R1,R2,R12,R14} ;If it worked, get registers
89 BICCSS PC,R14,#C_flag + V_flag ;And return with no error
90
91 ; --- Couldn't find it then ---
92
93 20tpl__find MOV R2,R1 ;Point to the template name
94 ADR R0,tpl__notfound ;Point to error message
95 BL msgs_error ;Translate the message
96 LDMFD R13!,{R1,R2,R12,R14} ;Unstack some registers
97 ORRS PC,R14,#V_flag ;Return with the error
98
99 tpl__notfound DCD 1
100 DCB "tplTNF",0
101
102 LTORG
103
104 ; --- template_find ---
105 ;
106 ; On entry: R0 == pointer to name to match
107 ;
108 ; On exit: R0 == pointer to window definition if found
109 ; May return an error
110 ;
111 ; Use: Locates a template in the list and gives you a pointer to
112 ; the corresponding window defintion. You may update the
113 ; definition to store an updated window state if you really
114 ; want to.
115 ;
116 ; Note that this call will fail if you attempt to find a
117 ; template which is held in the shared resources DLL.
118
119 EXPORT template_find
120 template_find ROUT
121
122 STMFD R13!,{R1,R2,R14} ;Save return address
123 MOV R2,R0 ;Remember the name
124 BL tpl__find ;Find the definition
125 BVS %10template_find ;If failed, skip onwards
126 BCC %05template_find ;If in resource DLL, skip
127 ADD R0,R0,#tlist_size ;Point to window def
128 LDMFD R13!,{R1,R2,R14} ;Return to caller
129 BICS PC,R14,#V_flag
130
131 ; --- It's in the resources DLL ---
132
133 05template_find ADR R0,tpl__notfound ;Point to error message
134 BL msgs_error ;Translate the message
135
136 ; --- Couldn't find the template ---
137
138 10template_find LDMFD R13!,{R1,R2,R14} ;Restore registers
139 ORRS PC,R14,#V_flag ;And return the error
140
141 LTORG
142
143 ; --- template_copy ---
144 ;
145 ; On entry: R0 == pointer to name to match
146 ;
147 ; On exit: R0 == pointer to copy of a window definition
148 ; May return an error
149 ;
150 ; Use: Returns a copy of a window template (for the use of the
151 ; dialogue box system mainly), including all indirected data
152 ; set up properly and everything. The copy is writable. To
153 ; get rid of the copy, call template_free.
154
155 EXPORT template_copy
156 template_copy ROUT
157
158 ; --- Find the copy first ---
159
160 STMFD R13!,{R1-R5,R14} ;Save some registers
161 BL tpl__find ;Find the definition
162 BVS %99template_copy ;If it failed, tidy up
163 BCC %50template_copy ;In resources -- handle it
164 MOV R5,R0 ;Keep pointer to definition
165
166 ; --- Now allocate the memory we need ---
167
168 LDR R0,[R5,#84+tlist_size] ;Get the number of icons
169 MOV R0,R0,LSL #5 ;Multiply by 32 for size
170 ADD R0,R0,#88+tlist_size ;Bump up by overhead
171 MOV R2,R0 ;Keep the size safe
172 BL alloc ;Allocate the memory
173 BCS %98template_copy ;If that failed, skip ahead
174 MOV R4,R0 ;Keep that pointer safe
175
176 ; --- Copy the window defintion over ---
177
178 MOV R1,R5 ;Point to the definition
179 MOV R0,R4 ;And my new block
180 BL fastMove ;Copy that data across
181
182 ; --- Now see if we need do anything else
183
184 LDR R0,[R5,#tlist_indsize] ;Get indirected data size
185 CMP R0,#0 ;Is there any?
186 BEQ %10template_copy ;If not, skip past this bit
187
188 ; --- Allocate the indirected space ---
189
190 MOV R2,R0 ;Look after the size
191 BL alloc ;Allocate the new block
192 BCS %97template_copy ;And tidy up if it failed
193
194 ; --- Copy indirected data over ---
195
196 LDR R1,[R5,#tlist_indptr] ;Find the old indirect block
197 BL fastMove ;Copy it over very quickly
198 STR R0,[R4,#tlist_indptr] ;Store the new block pointer
199
200 ; --- Now fix up all the references ---
201
202 SUB R5,R0,R1 ;Get the relocation offset
203 LDR R0,[R4,#56+tlist_size] ;Get the title bar flags
204 ADD R1,R4,#72+tlist_size ;Point to the title data
205 BL tpl__fixData ;Fix up that data
206
207 LDR R3,[R4,#84+tlist_size] ;Get the number of icons
208 ADD R2,R4,#88+tlist_size ;Point to the first icon
209 00template_copy SUBS R3,R3,#1 ;Decrement the icon counter
210 LDRGE R0,[R2,#16] ;Get the icon flags word
211 ADDGE R1,R2,#20 ;Point to the icon data
212 BLGE tpl__fixData ;And fix up the icon data
213 ADDGE R2,R2,#32 ;Move onto the next icon
214 BGE %00template_copy ;And move onto the next one
215
216 ; --- All done -- return the pointer ---
217
218 10template_copy ADD R0,R4,#tlist_size ;Point to the actual defn
219 LDMFD R13!,{R1-R5,R14} ;Unstack a load of registers
220 BICS PC,R14,#V_flag ;Return to caller
221
222 ; --- It's in the resources DLL ---
223
224 50template_copy LDMFD R13!,{R1-R5,R14} ;Restore these registers
225 B template_embedded ;Extract embedded definition
226
227 ; --- Error -- free the template block ---
228
229 97template_copy MOV R0,R4 ;Point to the template block
230 BL free ;Free up the block
231
232 ; --- Return the error ---
233
234 98template_copy BL alloc_error ;Find the correct error mesg
235
236 99template_copy LDMFD R13!,{R1-R5,R14} ;Restore the registers
237 ORRS PC,R14,#V_flag ;Return to caller
238
239 LTORG
240
241 ; --- tpl__fixData ---
242 ;
243 ; On entry: R0 == icon flags
244 ; R1 == pointer to icon data to fix
245 ; R5 == offset to bodge data by
246 ;
247 ; On exit: Registers preserved
248 ;
249 ; Use: Relocates indirected data by a given amount
250
251 tpl__fixData ROUT
252
253 TST R0,#&00000100 ;Is it indirected?
254 MOVEQS PC,R14 ;No -- return right now
255
256 ; --- Fix up icon data ---
257
258 STMFD R13!,{R14} ;Save the link register
259 LDR R14,[R1,#0] ;Get the data pointer
260 ADD R14,R14,R5 ;Relocate it
261 STR R14,[R1,#0] ;And store it back again
262
263 ; --- Is there validation data too? ---
264
265 TST R0,#&00000001 ;Does it contain text data?
266 LDRNE R14,[R1,#4] ;Yes -- get validation ptr
267 CMPNE R14,#-1 ;If the pointer sensible?
268 LDMEQFD R13!,{PC}^ ;No -- return
269
270 ; --- Relocate validation string pointer ---
271
272 ADD R14,R14,R5 ;Relocate it
273 STR R14,[R1,#4] ;Store it back in the block
274 LDMFD R13!,{PC}^ ;Return to caller
275
276 LTORG
277
278 ; --- template_embedded ---
279 ;
280 ; On entry: R0 == pointer to embedded template definition
281 ;
282 ; On exit: R0 == pointer to copy (as for template_copy)
283 ;
284 ; Use: Extracts an embedded template into a template block.
285 ; Embedded templates can be generated using the templAOF
286 ; program, and then linked into your application.
287
288 EXPORT template_embedded
289 template_embedded ROUT
290
291 STMFD R13!,{R1-R7,R14} ;Save some registers
292
293 ; --- First load the header out ---
294
295 LDMIA R0,{R3-R5} ;Load the three pointers out
296 ADD R3,R3,R0 ;Relocate the window pointer
297 ADD R4,R4,R0 ;Relocate the ind base ptr
298 ADD R5,R5,R0 ;Relocate the ind limit ptr
299 ADD R6,R0,#12 ;And find the relocation tbl
300
301 ; --- Allocate a block for the window definition ---
302
303 LDR R14,[R3,#84] ;Load the number of icons
304 MOV R0,#88+tlist_size ;Get the base memory req
305 ADD R0,R0,R14,LSL #5 ;Add space for the icons
306 SUB R2,R0,#tlist_size ;Keep size without extras
307 BL alloc ;Try to allocate the space
308 BLCS alloc_error ;If it failed, get error
309 BCS %99template_embedded ;And skip onwards
310 MOV R7,R0 ;Look after this pointer
311
312 ; --- Copy the window data over ---
313
314 ADD R0,R7,#tlist_size ;Point to window def area
315 MOV R1,R3 ;Point to the original def
316 BL fastMove ;Copy that over
317
318 ; --- Now handle the data ---
319
320 SUBS R0,R5,R4 ;Find indirected data size
321 STR R0,[R7,#tlist_indsize] ;Store the size away
322 STREQ R0,[R7,#tlist_indptr] ;If none, store null ptr
323 BEQ %10template_embedded ;And skip on to relocate
324
325 BL alloc ;Allocate the space
326 BLCS alloc_error ;If it failed, get error
327 BCS %98template_embedded ;And skip onwards
328 STR R0,[R7,#tlist_indptr] ;Store the pointer
329
330 ; --- Copy the data over ---
331
332 MOV R1,R4 ;Point to original data
333 SUB R2,R5,R4 ;Find the data size
334 BL fastMove ;Copy it over nicely
335
336 ; --- Finally do the relocation ---
337
338 10 MOV R5,R0 ;Look after indirected addr
339 BL resspr_area ;Find the sprite area
340 MOV R4,R0 ;Look after that too
341 ADD R0,R7,#tlist_size ;Find window definition
342
343 00 CMP R6,R3 ;Finished yet?
344 BCS %90template_embedded ;Yes -- wrap things up
345 LDR R14,[R6],#4 ;Load next directive
346 MOV R2,R14,LSR #28 ;Get the directive type
347 BIC R14,R14,#&F0000000 ;And the offset
348 ADD PC,PC,R2,LSL #2 ;Dispatch to handler
349 DCB "MDW!"
350 B %15template_embedded
351 B %20template_embedded
352 B %b00
353
354 15 LDR R2,[R0,R14] ;Load the word
355 ADD R2,R2,R5 ;Relocate for indirectedness
356 STR R2,[R0,R14] ;Store it back again
357 B %b00 ;Loop
358
359 20 STR R4,[R0,R14] ;Store the sprite area
360 B %b00 ;Loop
361
362 ; --- Finished -- return ---
363
364 90 LDMFD R13!,{R1-R7,R14} ;Load lots of registers
365 BICS PC,R14,#V_flag ;And return errorless
366
367 ; --- Errors -- tidy up ---
368
369 98 MOV R6,R0 ;Look after error pointer
370 MOV R0,R7 ;Get the template block
371 BL free ;Free it
372 MOV R0,R6 ;Restore error pointer
373
374 99 LDMFD R13!,{R1-R7,R14} ;Load lots of registers
375 ORRS PC,R14,#V_flag ;And return the error
376
377 LTORG
378
379 ; --- template_free ---
380 ;
381 ; On entry: R0 == pointer to block allocated with template_copy
382 ;
383 ; On exit: --
384 ;
385 ; Use: Frees a template copy created using template_copy.
386
387 EXPORT template_free
388 template_free ROUT
389
390 STMFD R13!,{R0,R1,R14} ;Save some registers
391 SUB R1,R0,#tlist_size ;Find base of block
392 LDR R0,[R1,#tlist_indptr] ;Get indirect data pointer
393 CMP R0,#0 ;Is there any indirect data?
394 BLNE free ;Yes -- free the memory
395 MOV R0,R1 ;Get the block pointer
396 BL free ;Free that too
397 LDMFD R13!,{R0,R1,PC}^ ;Return to caller
398
399 LTORG
400
401 ; --- template_load ---
402 ;
403 ; On entry: R0 == pointer to name of template file to load
404 ;
405 ; On exit: May return an error
406 ;
407 ; Use: Loads the specified template file, and adds its window
408 ; definitions into the template list so they can be used when
409 ; creating dialogue boxes or windows.
410 ;
411 ; If the templates can't be loaded (e.g. there isn't enough
412 ; memory) an error is generated (and can be caught using the
413 ; standard Sapphire except mechanism).
414
415 EXPORT template_load
416 template_load ROUT
417
418 ; --- We need a lot of registers! ---
419
420 STMFD R13!,{R0-R12,R14} ;Save the registers we want
421 WSPACE template_wspace ;Find my workspace
422
423 ; --- Find out how big the file is ---
424
425 MOV R1,R0 ;Point to the filename
426 MOV R0,#17 ;Info about file please
427 SWI XOS_File ;Try to load the file
428 BVS %99template_load ;If no luck, make the error
429
430 ; --- Allocate a heap block for it ---
431
432 MOV R0,R4 ;Get the template file size
433 BL alloc ;Allocate the block
434 BLCS alloc_error ;If it failed, get error
435 BCS %99template_load ;If no luck, make the error
436 MOV R8,R0 ;Guard pointer with life :-)
437
438 ; --- Load template file into buffer ---
439
440 MOV R0,#16 ;Load a file into memory
441 LDR R1,[R13,#0] ;Get the filename back
442 MOV R2,R8 ;Point to my buffer
443 MOV R3,#0 ;Load into my buffer
444 SWI XOS_File ;Load the file now
445 BVS %98template_load ;Bad news -- free block first
446
447 ; --- Now we can parse the file up ---
448
449 ADD R10,R8,#16 ;Find the first index entry
450 00template_load LDR R0,[R10,#0] ;Is this an empty entry?
451 CMP R0,#0 ;Just check quickly
452 BEQ %05template_load ;Yes -- we've finished
453
454 ADD R9,R8,R0 ;Point to the actual entry
455
456 LDR R1,[R10,#8] ;Get the entry type number
457 SUB R1,R1,#1 ;Convert it to zero-indexed
458 CMP R1,#(%11-%10)/4 ;Make sure it's recognised
459 BCS %02template_load ;No -- don't to it then
460 STMFD R13!,{R8,R12} ;Save workspace and base
461 MOV R12,R13 ;Point to this pair
462 MOV R14,PC ;Set up return address
463 ADD PC,PC,R1,LSL #2 ;Branch table dispatch
464 B %01template_load ;And link in the block
465
466 10template_load B tpl__loadWind ;Load a window definition
467 11template_load
468
469 01template_load LDMFD R13!,{R8,R12} ;Find workspace too
470 BVS %98template_load ;It failed miserably
471
472 ; --- Link the returned block into the list ---
473
474 LDR R1,template_list ;Find the list head
475 STR R1,[R0,#tlist_next] ;Make it this one's next ptr
476 STR R0,template_list ;And make this the list head
477
478 ; --- Move on to the next entry ---
479
480 02template_load ADD R10,R10,#24 ;Move to the next entry
481 B %00template_load ;And go back again
482
483 ; --- We finished loading the file -- free buffer ---
484
485 05template_load MOV R0,R8 ;Point to the file buffer
486 BL free ;Free the memory now
487
488 ; --- Now we can leave ---
489
490 LDMFD R13!,{R0-R12,R14} ;Return to caller
491 BICS PC,R14,#V_flag
492
493 ; --- Error encountered after block allocation ---
494
495 98template_load MOV R9,R0 ;Keep error pointer
496 MOV R0,R8 ;Point to the file buffer
497 BL free ;Free the memory now
498 MOV R0,R9 ;Restore error pointer
499
500 ; --- Error encountered before block allocation ---
501
502 99template_load ADD R2,R0,#4 ;Point to error message
503 ADR R0,tload__error ;Point to error skeleton
504 BL msgs_error ;Create the error message
505 ADD R13,R13,#4 ;Skip past stacked R0
506 LDMFD R13!,{R1-R12,R14} ;Return to caller
507 ORRS PC,R14,#V_flag ;With error indicator set
508
509 tload__error DCD 1
510 DCB "tplTLE",0
511
512 LTORG
513
514 template_wspace DCD 0
515
516 ; --- template_init ---
517 ;
518 ; On entry: R0 == pointer to application name
519 ;
520 ; On exit: --
521 ;
522 ; Use: Initialises the template list and font array, and loads the
523 ; `Templates' resource file.
524
525 EXPORT template_init
526 template_init ROUT
527
528 STMFD R13!,{R0,R1,R12,R14} ;Store some registers
529 WSPACE template_wspace ;Find my workspace
530 LDR R14,template_list ;Get the current list
531 CMP R14,#0 ;Is it silly?
532 LDMNEFD R13!,{R0,R1,R12,PC}^ ;No -- we're already running
533
534 BL alloc_init ;Make sure we can find memory
535 BL resspr_init ;This will initialise res too
536 BL except_init ;For atexit to tidy up later
537
538 ; --- Set up the workspace nicely ---
539
540 MOV R0,#0 ;Store null pointers
541 STR R0,template_list ;No templates yet
542 STR R0,template_fonts ;No fonts found either
543
544 ; --- Build the name in the scratchpad ---
545
546 ADR R0,tpl__templates ;Point to the resource name
547 MOV R1,R11 ;Point to scratchpad buffer
548 ADDS R0,R0,#0 ;Clear C and V flags
549 BL res_find ;Find the resource file
550
551 ; --- Load the file and return ---
552
553 BLCS template_load ;Load the file if it's there
554 SWIVS OS_GenerateError ;If it failed, make an error
555 LDMFD R13!,{R0,R1,R12,PC}^ ;Return to the caller
556
557 tpl__templates DCB "Templates",0
558
559 LTORG
560
561 ; --- tpl__killFont ---
562 ;
563 ; On entry: R12 == pointer to template workspace
564 ;
565 ; On exit: --
566 ;
567 ; Use: Loses loads of fonts when the application quits
568
569 tpl__killFont ROUT
570
571 STMFD R13!,{R0-R2,R14} ;Save some registers
572 LDR R1,template_fonts ;Find the font array
573 MOV R0,#255 ;Start at the top for this
574 00tpl__killFont LDRB R2,[R1,R0] ;Get the reference counter
575 01tpl__killFont SUBS R2,R2,#1 ;Decrement the counter
576 SWIGE Font_LoseFont ;Lose the font
577 BGE %01tpl__killFont ;And go round again
578 SUBS R0,R0,#1 ;Decrement the handle
579 BGE %00tpl__killFont ;And go round again
580 LDMFD R13!,{R0-R2,PC}^ ;And return to caller
581
582 LTORG
583
584 ;----- Template loading routines --------------------------------------------
585 ;
586 ; For all routines:
587 ;
588 ; On entry: R9 == pointer to entry in memory
589 ; R10 == pointer to index entry for this object
590 ; R12 == pointer to template base and workspace block
591 ;
592 ; On exit: If successful:
593 ; R0 == pointer to template entry to add into the list
594 ; V flag clear
595 ; If an error occurred:
596 ; R0 == pointer to standard error block
597 ; V flag set
598 ; R1-R9 may be corrupted
599
600 ; --- tpl__loadWind ---
601 ;
602 ; Use: Loads a window definition and converts it into a template
603 ; list item
604
605 tpl__loadWind ROUT
606
607 STMFD R13!,{R14} ;Just stack the return addr
608
609 ; --- Find out how many icons there are ---
610
611 ADD R0,R9,#84 ;Point to the right place
612 AND R1,R0,#3 ;Get the non-word-alignedness
613 BIC R0,R0,#3 ;And round down to word
614 LDMIA R0,{R2,R3} ;Get the two words we want
615 MOV R1,R1,LSL #3 ;Turn bytes into bits
616 MOV R8,R2,LSR R1 ;Get the bottom few bytes
617 RSB R1,R1,#32 ;Get the shift the other way
618 ORR R8,R8,R3,LSL R1 ;And copy in the top bytes
619
620 ; --- R8 now contains the number of icons ---
621
622 ; --- Allocate a template block ---
623
624 MOV R3,R8,LSL #5 ;Multiply the number by 32
625 ADD R3,R3,#88+tlist_size ;Add on window and list block
626 MOV R0,R3 ;I want to allocate memory
627 BL alloc ;Allocate the space
628 BLCS alloc_error ;If it failed, get error
629 BCS %99tpl__loadWind ;If it failed, return error
630 MOV R7,R0 ;Keep the pointer
631
632 ; --- Copy the window definition into the block ---
633
634 ADD R0,R7,#tlist_size ;Where to store definition
635 SUB R2,R3,#tlist_size ;Size of block to copy
636 MOV R1,R9 ;Point to the window def
637 BL fastMove ;And shunt the bytes over
638
639 ; --- We may as well copy the name over now too ---
640
641 ADD R1,R10,#12 ;Point to the template name
642 ADD R0,R7,#tlist_name ;Point to my block section
643 LDMIA R1,{R2-R4} ;Get the twelve bytes
644 STMIA R0,{R2-R4} ;Store them in my block
645 MOV R1,#0 ;And zero terminate
646 STRB R1,[R0,#12] ;Stop the string off nicely
647
648 ; --- Widge the sprite area ---
649
650 BL resspr_area ;Load the sprite area ptr
651 STR R0,[R7,#64+tlist_size] ;Store sprite area pointer
652
653 ; --- Now count the amount of indirected data ---
654
655 MOV R6,#0 ;Currently no indirected size
656
657 LDR R5,[R7,#56+tlist_size] ;Get the title bar flags
658 ADD R4,R7,#72+tlist_size ;Point to the title bar data
659 BL tpl__dataSize ;Add in the space required
660
661 MOV R0,R8 ;The number of icons I have
662 ADD R1,R7,#88+tlist_size ;Point to the first icon
663 00tpl__loadWind SUBS R0,R0,#1 ;Decrement the counter
664 LDRGE R5,[R1,#16] ;Get the flags word here
665 ADDGE R4,R1,#20 ;Point to the icon data
666 BLGE tpl__dataSize ;Add in the extra data
667 ADDGE R1,R1,#32 ;Point to the next icon defn
668 BGE %00tpl__loadWind ;And go back for the rest
669
670 ; --- We now have the data size in R6 ---
671
672 STR R6,[R7,#tlist_indsize] ;Store the buffer size away
673 CMP R6,#0 ;Is there any indirect space?
674 STREQ R6,[R7,#tlist_indptr] ;No -- store a null pointer
675 BEQ %01tpl__loadWind ;... and skip past allocation
676
677 ; --- Allocate the buffer properly ---
678
679 MOV R0,R6 ;Get the size of the block
680 BL alloc ;Allocate yet more memory
681 BLCS alloc_error ;If failed, get error
682 BCS %98tpl__loadWind ;If it failed, report error
683 MOV R6,R0 ;Point to the new buffer
684 STR R6,[R7,#tlist_indptr] ;Save indirected size away
685
686 ; --- Now copy the indirected data across ---
687 ;
688 ; We also fix up the pointers at the same time, and set up
689 ; any fonts that need loading.
690
691 01tpl__loadWind LDR R5,[R7,#56+tlist_size] ;Get the title bar flags
692 ADD R4,R7,#72+tlist_size ;Point to the title bar data
693 BL tpl__copyData ;Process the indirect data
694 ADD R5,R7,#56+tlist_size ;Point to the flags now
695 BL tpl__findFont ;And handle any fonts
696 BVS %97tpl__loadWind ;Quit if something went wrong
697
698 MOV R0,R8 ;The number of icons I have
699 ADD R1,R7,#88+tlist_size ;Point to the first icon
700 02tpl__loadWind SUBS R0,R0,#1 ;Decrement the counter
701 BLT %03tpl__loadWind ;If no more, skip ahead
702 LDR R5,[R1,#16] ;Get the flags word here
703 ADD R4,R1,#20 ;Point to the icon data
704 BL tpl__copyData ;Copy over the indirect data
705 ADD R5,R1,#16 ;Point to the flags now
706 BL tpl__findFont ;And handle any fonts
707 BVS %97tpl__loadWind ;Quit if something went wrong
708 ADD R1,R1,#32 ;Point to the next icon defn
709 B %02tpl__loadWind ;Now go back for the rest
710
711 ; --- The excitement's over now, so that's it ---
712
713 03tpl__loadWind MOV R0,R7 ;Point at the template block
714 LDMFD R13!,{R14} ;Get the link register out
715 BICS PC,R14,#V_flag ;And return no errors
716
717 ; --- Something screwed up -- deallocate both blocks ---
718
719 97tpl__loadWind MOV R9,R0 ;Save error pointer
720 LDR R0,[R7,#tlist_indptr] ;Find the indirect block addr
721 BL free ;Free indirect data block
722 MOV R0,R9 ;Restore error pointer
723
724 ; --- Error occurred -- free the template block ---
725
726 98tpl__loadWind MOV R9,R0 ;Save error pointer
727 MOV R0,R7 ;Point to template block
728 BL free ;Free the template block
729 MOV R0,R9 ;Restore error pointer
730
731 ; --- Error occurred -- return with V set ---
732
733 99tpl__loadWind LDMFD R13!,{R14} ;Get the link register
734 ORRS PC,R14,#V_flag ;Set the error indicator
735
736 LTORG
737
738 ;----- Support functions ----------------------------------------------------
739
740 ; --- tpl__dataSize ---
741 ;
742 ; On entry: R4 == pointer to icon data
743 ; R5 == icon flags word
744 ; R6 == counter to increment
745 ; R7 == pointer to window block
746 ; R8 == number of icons in the window
747 ; R9 == pointer to the window definition in the template file
748 ; R10 == pointer to index for current window
749 ; R12 == pointer to template base and workspace block
750 ;
751 ; On exit: R6 incremented by an appropriate amount
752 ; Everything else preserved (except R14, obviously!)
753 ;
754 ; Use: Counts the amount of indirected space required for a given
755 ; icon flags/data pair and adds it into a running total
756
757 tpl__dataSize ROUT
758
759 ; --- Make sure there's something to do ---
760
761 TST R5,#&00000100 ;Test indirected bit
762 MOVEQS PC,R14 ;If not indirected, go away
763
764 ; --- Locate and count the indirected data string ---
765
766 STMFD R13!,{R14} ;Save some registers
767 LDR R14,[R4,#8] ;Get the indirect buffer size
768 ADD R6,R6,R14 ;And add this onto the count
769
770 ; --- Check if there's a validation string ---
771
772 TST R5,#&00000001 ;Is the `Is text' bit on?
773 LDRNE R14,[R4,#4] ;Yes -- get validation ptr
774 CMPNE R14,#-1 ;Is it a sensible pointer?
775 LDMEQFD R13!,{PC}^ ;If not, we're done for now
776
777 ; --- Count length of validation string ---
778
779 STMFD R13!,{R0} ;Save another register
780 ADD R0,R14,R9 ;Point to string in memory
781 BL str_len ;Find its length
782 ADD R0,R0,#1 ;Account for the terminator
783 ADD R6,R6,R0 ;Add this to the counter
784 LDMFD R13!,{R0,PC}^ ;And return to the caller
785
786 LTORG
787
788 ; --- tpl__copyData ---
789 ;
790 ; On entry: R4 == pointer to icon data
791 ; R5 == icon flags word
792 ; R6 == pointer to free part of buffer
793 ; R7 == pointer to window block
794 ; R8 == number of icons in the window
795 ; R9 == pointer to the window definition in the template file
796 ; R10 == pointer to index for current window
797 ; R12 == pointer to template base and workspace block
798 ;
799 ; On exit: R6 incremented by an appropriate amount
800 ; Everything else preserved (except R14, obviously!)
801 ;
802 ; Use: Copies indirected data from an icon definition into the
803 ; buffer given and fixes up pointers in the definition
804
805 tpl__copyData ROUT
806
807 ; --- Make sure there's something to do here ---
808
809 TST R5,#&00000100 ;Check the indirected bit
810 MOVEQS PC,R14 ;If unset, return right now
811
812 ; --- Handle basic indirected data ---
813
814 STMFD R13!,{R0,R1,R14} ;Stack some registers
815 LDR R1,[R4,#0] ;Get the indirected pointer
816 STR R6,[R4,#0] ;Store the new pointer in
817 ADD R1,R9,R1 ;Offset by window address
818 MOV R0,R6 ;Point to free bit of bufffer
819 BL str_cpy ;Copy (and null-terminate)
820 LDR R14,[R4,#8] ;Get the indirect buffer size
821 ADD R6,R6,R14 ;Move buffer pointer on by it
822
823 ; --- Check for validation string presence ---
824
825 TST R5,#&00000001 ;Is the `Is text' bit on?
826 LDRNE R14,[R4,#4] ;Yes -- get validation ptr
827 CMPNE R14,#-1 ;Is it a sensible pointer?
828 LDMEQFD R13!,{R0,R1,PC}^ ;If not, we're done
829
830 ; --- Handle the validation string ---
831
832 STR R6,[R4,#4] ;Store the new pointer
833 ADD R1,R9,R14 ;Point to the validation str
834 MOV R0,R6 ;Point to the bit of buffer
835 BL str_cpy ;And copy the string across
836 ADD R6,R0,#1 ;Point R6 past string term
837 LDMFD R13!,{R0,R1,PC}^ ;That's it from us, then
838
839 LTORG
840
841 ; --- tpl__findFont ---
842 ;
843 ; On entry: R5 == pointer to icon flags word
844 ; R6 == pointer to free part of buffer
845 ; R7 == pointer to window block
846 ; R8 == number of icons in the window
847 ; R9 == pointer to the window definition in the template file
848 ; R10 == pointer to index for current window
849 ; R12 == pointer to template base and workspace block
850 ;
851 ; On exit: Everything preserved except R4 (and R14, obviously!)
852 ;
853 ; Use: Fixes up an icon's anti-aliased font data.
854
855 tpl__findFont ROUT
856
857 LDR R4,[R5] ;Get the icon flags word
858 TST R4,#&00000040 ;Is it antialiased?
859 TSTNE R4,#&00000001 ;Make sure it's text too
860 BICEQS PC,R14,#V_flag ;If not, return no error
861
862 ; --- Now to business -- ensure we have a font table ---
863
864 STMFD R13!,{R0-R3,R5,R12,R14} ;Save some registers
865 LDMIA R12,{R5,R12} ;Load base and workspace
866 LDR R0,template_fonts ;Find font array pointer
867 CMP R0,#0 ;Is it null?
868 BEQ %00tpl__findFont ;Yes -- allocate it
869
870 ; --- Now locate the font table in the file ---
871
872 01tpl__findFont LDR R3,[R5,#0] ;Get the font table offset
873 ADD R3,R5,R3 ;Convert it to a pointer
874
875 ; --- Find internal font handle and get table entry ---
876
877 MOV R0,R4,LSR #24 ;Leave only the font handle
878 SUB R0,R0,#1 ;Convert to 0-indexed
879 STMFD R13!,{R4,R5} ;Need some more registers!!
880 ADD R4,R3,R0,LSL #4 ;R4 = R3 + R0 * 16
881 ADD R4,R4,R0,LSL #5 ;Now R4 = R3 + R0 * 48
882
883 ; --- Now we must load the font width and height ---
884 ;
885 ; The problem is that they're not on word boundaries, so
886 ; we must do clever-dick things with the barrel shifter.
887
888 AND R0,R3,#3 ;Get the bottom two bits
889 BIC R1,R3,#3 ;Word align the base address
890 LDMIA R1,{R2,R3,R14} ;Get the width and height
891 MOV R0,R0,LSL #3 ;Convert bits to bytes
892 RSB R1,R0,#32 ;Get the other shift too
893 MOV R2,R2,LSR R0 ;Shift the bits down here
894 ORR R2,R2,R3,LSL R1 ;And add in the top bits
895 MOV R3,R3,LSR R0 ;Shift down bottom bits
896 ORR R3,R3,R14,LSL R1 ;And add in the top bits
897
898 ; --- We are now in a position to find the font ---
899
900 ADD R1,R4,#8 ;Point to the font name
901 MOV R4,#0 ;Default x scaling
902 MOV R5,#0 ;Default y scaling
903 SWI Font_FindFont ;Try very hard to find it
904 LDMFD R13!,{R4,R5} ;Restore these registers
905 ADDVS R13,R13,#4 ;If it failed, skip R0,
906 LDMVSFD R13!,{R1-R3,PC} ;... and restore regs
907
908 ; --- Now bump the item in the font array ---
909
910 LDR R1,template_fonts ;Find the font array
911 LDRB R2,[R1,R0] ;Get counter for the handle
912 ADD R2,R2,#1 ;Bump the counter a bit
913 STRB R2,[R1,R0] ;And store it away again
914
915 ; --- Bodge the icon flags word for the new handle ---
916
917 BIC R4,R4,#&FF000000 ;Clear out the old handle
918 ORR R4,R4,R0,LSL #24 ;Bring in the new...
919 STR R4,[R5] ;Store the new flags word
920 LDMFD R13!,{R0-R3,R5,R12,R14} ;Restore the registers
921 BICS PC,R14,#V_flag ;And return with no error
922
923 ; --- Create the font array if it's not there ---
924
925 00tpl__findFont MOV R0,#256 ;One byte for each font
926 BL alloc ;Allocate the memory
927 BLCS alloc_error ;If failed, get error
928 ADDCS R13,R13,#4 ;If it failed, bump R13
929 LDMCSFD R13!,{R1-R3,R5,R12,PC} ;... and return with error
930 STR R0,template_fonts ;Store the new pointer
931
932 ; --- Clear the font array to 0s ---
933
934 MOV R1,#256 ;The size of the array
935 MOV R2,#0 ;Value to initialise with
936 BL mem_set ;Clear out the array
937
938 ; --- Register our tidy-up routine ---
939
940 ADR R0,tpl__killFont ;Point to tidy up function
941 MOV R1,R12 ;Point to my workspace
942 BL except_atExit ;Register it properly
943 B %01tpl__findFont ;Return to the main proc
944
945 LTORG
946
947 ;----- The list structure ---------------------------------------------------
948
949 ^ 0
950 tlist_start # 0
951
952 tlist_next # 4 ;Pointer to the next one
953 tlist_name # 16 ;Name of this template
954 tlist_indptr # 4 ;Pointer to indirect data
955 tlist_indsize # 4 ;Size of indirect data
956 ; Window definition follows
957
958 tlist_size # 0 ;Size of that structure
959
960 ;----- Workspace ------------------------------------------------------------
961
962 ^ 0,R12
963 template_wstart # 0
964
965 template_list # 4 ;List head for templates
966 template_fonts # 4 ;Font array if we need one
967
968 template_wsize EQU {VAR}-template_wstart
969
970 AREA |Sapphire$$LibData|,CODE,READONLY
971
972 DCD template_wsize
973 DCD template_wspace
974 DCD 256
975 DCD template_init
976
977 ;----- That's all, folks ----------------------------------------------------
978
979 END