Create readable text `.bas' for each tokenized BASIC `,ffb' file.
[ssr] / StraySrc / SapphToys / !SWIlist / bs / swiList.bas
1 REM
2 REM swiList.bs
3 REM
4 REM Build SWI name include files
5 REM
6 REM © 1995 Straylight
7 REM
8
9 REM -- Standard header ------------------------------------------------------
10
11 ON ERROR ERROR 0,"*** ERROR: "+REPORT$+" ["+STR$(ERL)+"]"
12
13 LIBRARY "libs:BAS"
14 PROCbas_init
15
16 PROCbas_aofInit(&8000)
17
18 V_flag=1<<28
19 C_flag=1<<29
20
21 FOR o=4 TO 6 STEP 2
22
23 [ opt o
24 FNpass
25
26 ;----- Revision history -----------------------------------------------------
27 ;
28 ; Version By Change
29 ;
30 ; 1.xx MDW Old version written in C using STEEL.
31 ;
32 ; 2.00 MDW Rewrite from scratch in assembler using Sapphire.
33 ; Keep SWI names in flex block, allow user format
34 ; files, and add SWIs from modules dropped onto icon.
35 ;
36 ; 2.01 MDW Replaced format file loading with a chunk file, to
37 ; support multiple programming languages. Added
38 ; submenu to `Save list' for selecting which language
39 ; to use.
40 ;
41 ; 2.02 MDW Added %d format specifier to output generation time/
42 ; date in given style. Also added revision history ;-)
43 ;
44 ; 2.03 MDW Added confirm on quit option, and prevented saving
45 ; a dump from SWIList back into itself.
46 ;
47 ; 2.04 MDW Tidied up initialisation a little, and made it
48 ; register the heap routines as allocators for smaller
49 ; WimpSlot.
50 ;
51 ; 2.05 MDW Fiddled help message generation a little to (a)
52 ; do message translation of the format names and (b)
53 ; use %0 rather than the less pretty %9 in the help
54 ; skeleton.
55 ;
56 ; 2.06 MDW Added full pathname for dump save, so you don't have
57 ; to dig up the application to save the dump each time.
58 ;
59 ; 2.07 MDW Used SEH for error handling, instead of raw except-
60 ; level stuff.
61
62 ;----- External dependencies ------------------------------------------------
63
64 ; --- Sapphire library ---
65
66 FNget ("sapphire:alloc")
67 FNget ("sapphire:buttons")
68 FNget ("sapphire:chunk")
69 FNget ("sapphire:defHandler")
70 FNget ("sapphire:errorBox")
71 FNget ("sapphire:event")
72 FNget ("sapphire:fastMove")
73 FNget ("sapphire:flex")
74 FNget ("sapphire:heap")
75 FNget ("sapphire:help")
76 FNget ("sapphire:hour")
77 FNget ("sapphire:ibicon")
78 FNget ("sapphire:libOpts")
79 FNget ("sapphire:menu")
80 FNget ("sapphire:menuDefs")
81 FNget ("sapphire:msgs")
82 FNget ("sapphire:note")
83 FNget ("sapphire:progInfo")
84 FNget ("sapphire:ptr")
85 FNget ("sapphire:report")
86 FNget ("sapphire:res")
87 FNget ("sapphire:resources")
88 FNget ("sapphire:sapphire")
89 FNget ("sapphire:seh")
90 FNget ("sapphire:string")
91 FNget ("sapphire:warning")
92
93 FNget ("sapphire:choices.choices")
94
95 FNget ("sapphire:xfer.load")
96 FNget ("sapphire:xfer.saveAs")
97 FNget ("sapphire:xfer.save")
98 FNget ("sapphire:xfer.xsave")
99
100 ; --- Link-time generated strings ---
101
102 FNimport("cright")
103 FNimport("version")
104
105 ;----- Initialisation -------------------------------------------------------
106
107 FNarea ("Client$$Code","CODE,READONLY")
108
109 ; --- main ---
110 ;
111 ; On entry; --
112 ;
113 ; On exit; Via OS_Exit
114 ;
115 ; Use; Allows saving of header files containing SWI name-number
116 ; mappings.
117
118 .main FNentry
119
120 adr r0,FNlitsz("SWIList") ;Point to application name
121 mov r1,#sl__wSize ;Get my workspace size
122 mov r2,#0 ;Default stack size
123 bl sapphire_init ;Start up the library
124 bl sl__preInit ;Do pre-initialisation stuff
125 bl sapphire_libInit ;Initialise rest of library
126 bl sl__init ;Initialise me
127
128 bl seh_throwErrors ;Make errors throw exceptions
129 bl report_catchAll ;And catch exceptions
130
131 .sl__pollLoop mov r0,#1 ;Don't have idle events
132 add r1,r12,#sl__pollBlock ;Point to the poll block
133 bl event_poll ;Handle an event
134 blcc sl__unknowns ;Handle unknown events
135 blcc defHandler ;Pass it on if unrecognised
136 b sl__pollLoop ;And carry on round forever
137
138 FNltorg
139
140 ; --- sl__preInit ---
141 ;
142 ; On entry; --
143 ;
144 ; On exit; R0-R10 corrupted
145 ;
146 ; Use; Does initialisation of things before the main Sapphire
147 ; library awakes.
148
149 .sl__preInit stmfd r13!,{r14} ;Save a register away
150 bl resources_init ;Use shared resource DLL
151 bl hour_init ;Wake up the hourglass system
152 bl hour_on ;And turn it on
153 ldr r0,[r11,#sapph_appName] ;Find the application name
154 bl heap_init ;Initialise the resizing heap
155 bl heap_useHeap ;Register it as an allocator
156 adr r0,sl__sapphOpts ;Point to options block
157 bl libOpts_register ;Register the options
158 ldmfd r13!,{pc}^ ;Return to caller when done
159
160 .sl__sapphOpts FNlibOpt("MENU")
161 dcd 8192
162 FNlibOpts_end
163
164 FNltorg
165
166 ; --- sl__init ---
167 ;
168 ; On entry; --
169 ;
170 ; On exit; --
171 ;
172 ; Use; Initialises SWIList's workspace.
173
174 .sl__init stmfd r13!,{r14} ;Save some registers
175 bl sl__initWS ;Set up my workspace
176 bl sl__loadFormat ;Load the user's format file
177 bl sl__initList ;Create the SWI list
178 bl sl__iconBar ;Create my icon
179 bl sl__setFlags ;Finally set the flags up
180 ldmfd r13!,{pc}^ ;And return to caller
181
182 FNltorg
183
184 ; --- sl__initWS ---
185 ;
186 ; On entry; --
187 ;
188 ; On exit; R0-R10 corrupted
189 ;
190 ; Use; Initialises the application's workspace.
191
192 .sl__initWS stmfd r13!,{r14} ;Save the link register
193 mov r14,#0 ;Zero the anchor pointer
194 str r14,[r12,#sl__flags] ;Clear the flags initially
195 str r14,[r12,#sl__anchor] ;Say we have no block yet
196 str r14,[r12,#sl__modNames] ;No module name table
197 str r14,[r12,#sl__format] ;No format loaded yet
198 ldmfd r13!,{pc}^ ;And return to caller
199
200 FNltorg
201
202 ; --- sl__loadFormat ---
203 ;
204 ; On entry; --
205 ;
206 ; On exit; R0-R10 corrupted
207 ;
208 ; Use; Loads SWIList's format file.
209
210 .sl__loadFormat stmfd r13!,{r14} ;Save the link register
211
212 ; --- Enable the Choices support ---
213
214 mov r0,#1 ;Enable `Choices' support
215 bl choices_useChoices ;Allow read-only use nicely
216
217 ; --- Create the format chunk file ---
218
219 bl chunk_create ;Create a chunk file
220 swivs "OS_GenerateError" ;Be unhappy if it fails
221 str r0,[r12,#sl__format] ;Save this away
222
223 ; --- Now do the actual load operation ---
224
225 adr r0,FNlitsz("Format") ;Point to the leafname
226 mov r1,r11 ;Build name in scratchpad
227 mov r2,#0 ;I want to read the file
228 bl choices_find ;Translate the name
229 mov r1,r0 ;Point to the name
230 sub r13,r13,#4 ;Make a flex anchor
231 mov r2,r13 ;Point to this anchor
232 bl load_file ;Load the file into it
233 ldrvc r0,[r12,#sl__format] ;Find the format handle
234 movvc r1,r13 ;And point to the anchor
235 blvc chunk_read ;Add that to the chunks
236 mov r0,r13 ;Point to that anchor again
237 bl flex_free ;Get rid of the block
238 add r13,r13,#4 ;And restore the stack
239
240 ; --- Set flag if any format chunks found ---
241
242 ldr r0,[r12,#sl__format] ;Find the format handle
243 mov r1,#0 ;Start enumerating
244 bl chunk_enum ;Are there any chunks?
245 ldrcc r14,[r12,#sl__flags] ;Yes -- get the flags
246 orrcc r14,r14,#slFlag__format ;Set the format flag
247 strcc r14,[r12,#sl__flags] ;And save them back again
248 ldmfd r13!,{pc}^ ;Return to caller when done
249
250 FNltorg
251
252 ; --- sl__initList ---
253 ;
254 ; On entry; --
255 ;
256 ; On exit; R0-R10 corrupted
257 ;
258 ; Use; Initialises the SWI table, either by loading a saved dump
259 ; or by scanning the modules in memory.
260
261 .sl__initList stmfd r13!,{r14} ;Save the link register
262 adr r0,FNlitsz("SWIDump") ;Point to the leafname
263 mov r1,r11 ;Build name in scratchpad
264 mov r2,#0 ;I want to read the file
265 bl choices_find ;Translate the name
266 mov r1,r0 ;Point to the name
267 bl sl__loadDmp ;Load the default dump
268 blvc sl__doneDmp ;If OK, set the rest up
269 blvs sl__initBlock ;Otherwise, scan the modules
270 ldmfd r13!,{pc}^ ;Return to caller when done
271
272 FNltorg
273
274 ; --- sl__iconBar ---
275 ;
276 ; On entry; --
277 ;
278 ; On exit; --
279 ;
280 ; Use; Sets up the icon bar icon.
281
282 .sl__iconBar stmfd r13!,{r0-r6,r14} ;Save some registers
283 adr r0,FNlitsz("!swilist") ;Point to sprite to use
284 mov r1,#0 ;No text buffer here
285 mvn r2,#NOT(-1) ;Put icon on the left
286 mov r3,#0 ;Normal priority please
287 adr r4,sl__ibEvents ;Point to event handler
288 mov r5,#0 ;Pass no document handle
289 mov r6,r12 ;Pass workspace pointer
290 bl ibicon_create ;Create the icon nicely
291 swivs "OS_GenerateError" ;If it failed, halt program
292 ldmfd r13!,{r0-r6,pc}^ ;And return to caller
293
294 FNltorg
295
296 ; --- sl__ibEvents ---
297 ;
298 ; On entry; R0 == event code
299 ;
300 ; On exit; --
301 ;
302 ; Use; Handles events for the icon bar icon.
303
304 .sl__ibEvents cmp r0,#(sl__ibe10-sl__ibe00)/4
305 addcc pc,pc,r0,lsl #2 ;Dispatch through branch tbl
306 movs pc,r14 ;Ignore unknown events
307
308 .sl__ibe00 movs pc,r14 ;Ignore Select clicks
309 b sl__ibMenu ;Handle a menu click
310 movs pc,r14 ;Ignore Adjust clicks
311 b sl__ibLoad ;Handle a load/save request
312 b sl__ibLoad ;We treat them all the same
313 b sl__ibHelp ;Handle a help request
314 .sl__ibe10
315 ; --- Handle a menu click ---
316
317 .sl__ibMenu stmfd r13!,{r0-r3,r14} ;Save some registers
318 adr r0,sl__imDef ;Point to the menu definition
319 adr r1,sl__imEvents ;Point to menu handler code
320 mov r2,r10 ;Pass it the doc handle
321 mov r3,r12 ;And my workspace address
322 bl menu_create ;Display the menu nicely
323 ldmfd r13!,{r0-r3,pc}^ ;And return to caller
324
325 .sl__imDef FNmenu("SWIList")
326 FNmenu_item("slINF")
327 FNmenu_subWarn
328 FNmenu_ruleOff
329 FNmenu_item("slSVL")
330 FNmenu_r12Data
331 FNmenu_iShade(sl__flags,slFlag__savable)
332 FNmenu_subWarn
333 FNmenu_noWarn
334 FNmenu_item("slSVD")
335 FNmenu_r12Data
336 FNmenu_iShade(sl__flags,slFlag__block)
337 FNmenu_subWarn
338 FNmenu_noWarn
339 FNmenu_item("slSCN")
340 FNmenu_item("slRFM")
341 FNmenu_subWarn
342 FNmenu_ruleOff
343 FNmenu_item("slQUT")
344 FNmenu_end
345
346 ; --- Handle a help request ---
347
348 .sl__ibHelp stmfd r13!,{r0,r14} ;Save some registers
349 adr r0,FNlitsz("slhIB") ;Point to a message tag
350 bl msgs_lookup ;Translate the tag
351 bl help_add ;And add it to the help
352 ldmfd r13!,{r0,pc}^ ;Return to caller
353
354 ; --- Handle a load event ---
355
356 .sl__ibLoad stmfd r13!,{r0-r2,r14} ;Save some registers
357 bl event_last ;Find the last event
358 ldr r0,[r1,#40] ;Load the filetype
359 ldr r14,FNlitw(&FFA) ;Get the module filetype
360 cmp r0,r14 ;Do these match
361 beq sl__ibLdMod ;Yes -- handle that then
362 ldr r14,FNlitw(&FFD) ;Get the data filetype
363 cmp r0,r14 ;Do these match
364 beq sl__ibLdDump ;Yes -- handle that then
365 ldmfd r13!,{r0-r2,pc}^ ;Return to caller
366
367 ; --- Handle loading a module ---
368
369 .sl__ibLdMod adr r0,sl__lMod ;Point to load block
370 mov r1,r10 ;Get document handle
371 mov r2,r12 ;And workspace address
372 bl load ;Do the load operation
373 ldmfd r13!,{r0-r2,pc}^ ;And return when done
374
375 .sl__lMod b sl__ibMod
376 b load_killBuf
377 b load_extendBuf
378 b load_doneBuf
379 b sl__loadMod
380 b sl__doneMod
381 b sl__lfMod
382
383 ; --- Handle loading a dump ---
384
385 .sl__ibLdDump ldr r14,[r12,#sl__flags] ;Load the flags word
386 tst r14,#slFlag__saving ;Are we saving currently?
387 bne sl__ild50 ;Yes -- moan at user then
388
389 adr r0,sl__lDmp ;Point to load block
390 mov r1,r10 ;Get document handle
391 mov r2,r12 ;And workspace address
392 bl load ;Yes -- start a load op
393 ldmfd r13!,{r0-r2,pc}^ ;And return to caller
394
395 .sl__ild50 adr r0,FNliterr(1,"slCSII") ;Point to error block
396 bl msgs_error ;Translate the message
397 mov r1,#1 ;Only display OK button
398 bl errorBox ;Display the error
399 ldmfd r13!,{r0-r2,pc}^ ;And return to caller
400
401 .sl__lDmp b sl__ibDmp
402 b load_killBuf
403 b load_extendBuf
404 b load_doneBuf
405 b sl__loadDmp
406 b sl__doneDmp
407 b sl__lfDmp
408
409 FNltorg
410
411 ; --- sl__imEvents ---
412 ;
413 ; On entry; R0 == event code
414 ; R1 == item number
415 ;
416 ; On exit; --
417 ;
418 ; Use; Handles events from the icon bar menu.
419
420 .sl__imEvents cmp r0,#mEvent_help ;A help request, perchance?
421 beq sl__imHelp ;Yes -- deliver help on it
422 cmp r0,#mEvent_select ;Is this a select event?
423 cmpne r0,#mEvent_subMenu ;Or a submenu opening?
424 movnes pc,r14 ;No -- ignore the event
425
426 cmp r1,#(sl__ime10-sl__ime00)/4
427 addcc pc,pc,r1,lsl #2 ;Dispatch by item number
428 movs pc,r14 ;Ignore unknown item numbers
429
430 .sl__ime00 b sl__imInfo ;Display the info box
431 b sl__imSave ;Save the SWI list
432 b sl__imDump ;Save a SWI dump
433 b sl__initBlock ;Reset the block
434 b sl__imRefresh ;Refresh a particular module
435 b sl__imQuit ;Close down the program
436 .sl__ime10
437
438 ; --- Send a help message ---
439
440 .sl__imHelp stmfd r13!,{r0,r14} ;Save some registers
441 adr r0,FNlitsz("slhIM") ;Find the message base tag
442 bl menu_help ;Give help on the item
443 ldmfd r13!,{r0,pc}^ ;And return to caller
444
445 ; --- Display the info window ---
446
447 .sl__imInfo stmfd r13!,{r0-r2,r14} ;Save some registers
448 adr r0,FNlitsz("slPUR") ;Point to purpose message
449 bl msgs_lookup ;Translate message tag
450 ldr r1,FNlitw(cright) ;Find the copyright string
451 ldr r2,FNlitw(version) ;And the version string
452 bl progInfo ;Display the box
453 movvs r1,#1 ;If it failed, display error
454 blvs errorBox ;In a pretty error box
455 ldmfd r13!,{r0-r2,pc}^ ;And return to caller
456
457 FNltorg
458
459 ; --- Dislplay the menu of formats ---
460
461 .sl__imSave cmp r0,#mEvent_subMenu ;Make sure this is a submenu
462 movnes pc,r14 ;No -- not interested
463
464 stmfd r13!,{r0-r5,r14} ;Save some registers
465 adr r0,sl__fmtTitle ;Point to the title
466 mov r1,#0 ;No handler for that
467 bl menu_create ;Set that up to display
468
469 ldr r4,[r12,#sl__format] ;Load the format chunk file
470 mov r1,#0 ;Read first chunk name
471 .loop mov r0,r4 ;Pop it in R0 for a bit
472 bl chunk_enum ;Get the next chunk
473 ldmcsfd r13!,{r0-r5,pc}^ ;Return when finished
474 str r2,[r1,#4] ;Save pointer to name
475 mov r2,r1 ;Point to the anchor
476 mov r5,r1 ;Look after continuation
477 adr r0,sl__fmtMenu ;Point to menu skeleton
478 adr r1,sl__fmtHandler ;Point to handler routine
479 mov r3,r12 ;Pass workspace in R12
480 bl menu_create ;Add that to the list
481 mov r1,r5 ;Get the continuation value
482 b loop ;And go back to the loop
483
484 .sl__fmtTitle FNmenu("slSVFT")
485 FNmenu_end
486
487 .sl__fmtMenu FNmenu_itemInd(4)
488 FNmenu_subWarn
489 FNmenu_end
490
491 FNltorg
492
493 ; --- Dislplay the dump box ---
494
495 .sl__imDump stmfd r13!,{r0-r5,r14} ;Save some registers
496 ldr r0,[r12,#sl__used] ;Load the actual block size
497 ldr r1,FNlitw(&ffd) ;Output as a data file
498 add r2,r12,#sl__dumpFile ;Point to the dump file name
499 adr r3,sl__dumpDef ;Point to handler block
500 mov r4,r10 ;Pass document handle
501 mov r5,r12 ;And pass the workspace addr
502 bl saveAs ;Try to do the save op
503 bvs sl__imd90 ;Tidy up if it failed
504 ldr r14,[r12,#sl__flags] ;Load the current flags
505 orr r14,r14,#slFlag__saving ;Say we're now saving
506 str r14,[r12,#sl__flags] ;Save the flags back again
507 ldmfd r13!,{r0-r5,pc}^ ;And return to caller
508
509 .sl__imd90 mov r1,#1 ;If it failed, report error
510 bl errorBox ;In a nice error box
511 ldmfd r13!,{r0-r5,pc}^ ;And return to caller
512
513 .sl__dumpDef FNs ("slSDT") ;Title for the save box
514 b sl__svdDone ;Handle box closing
515 b sl__saveDump ;Save to a disk file
516 b sl__sendDump ;Send to another application
517 movs pc,r14 ;Ignore completion
518 b sl__svdFail ;Tidy up after a failure
519
520 FNltorg
521
522 ; --- Display a menu of modules to refresh ---
523
524 .sl__imRefresh cmp r0,#mEvent_subMenu ;Is this a submenu?
525 movnes pc,r14 ;No -- go away then
526 stmfd r13!,{r0-r7,r14} ;Save some registers
527
528 ; --- Free the old title block ---
529
530 ldr r0,[r12,#sl__modNames] ;Load the pointer
531 cmp r0,#0 ;Is the block allocated?
532 blne free ;Yes -- deallocate it them
533 movne r14,#0 ;And clear the pointer out
534 strne r14,[r12,#sl__modNames] ;Done that
535
536 ; --- Enumerate interesting modules ---
537
538 mov r6,#0 ;Size of block required
539 mov r1,#0 ;Start at the beginning
540
541 ; --- Read the next module ---
542
543 .loop mov r0,#12 ;Enumerate module names
544 mov r2,#0 ;Not interested in instances
545 swi "XOS_Module" ;Read the next module
546 bvs sl__imRefAlloc ;No more -- go to next phase
547
548 ; --- Update the arguments for next call ---
549
550 cmp r2,#0 ;Is there another instance?
551 addne r1,r1,#1 ;No -- update manually
552
553 ; --- See whether this module was interesting ---
554
555 ldr r14,[r3,#&20] ;Load the SWI handler offset
556 cmp r14,#0 ;Does this look sensible?
557 addne r6,r6,#8 ;Yes -- add another word
558 b loop ;Get more modules
559
560 ; --- Allocate the block ---
561
562 .sl__imRefAlloc mov r0,r6 ;Get the required size
563 bl alloc ;Allocate the block
564 blcs alloc_error ;If it failed, point to error
565 bcs sl__imRefError ;And handle that
566 str r0,[r12,#sl__modNames] ;Store pointer for later
567 mov r7,r0 ;Point to the block start
568
569 ; --- Set up the title block ---
570
571 adr r0,sl__rfmTitle ;Point to the title block
572 adr r1,sl__rfmKernel ;Point to event handler
573 mov r2,r10 ;Pass my R10 value
574 mov r3,r12 ;And my R12 value
575 bl menu_create ;Create the title
576
577 ; --- Initialise for module scanning ---
578
579 mov r6,#0 ;Current module number
580
581 ; --- Read the next module ---
582
583 .loop mov r0,#12 ;Enumerate module names
584 mov r1,r6 ;Get next module number
585 mov r2,#0 ;And next module name
586 swi "XOS_Module" ;Read the next module
587 ldmvsfd r13!,{r0-r7,pc}^ ;Return when done
588
589 ; --- Update the arguments for next call ---
590
591 cmp r2,#0 ;Is there another instance?
592 moveq r6,r1 ;Yes -- store it normally
593 addne r6,r1,#1 ;No -- update manually
594
595 ; --- See whether this module was interesting ---
596
597 ldr r14,[r3,#&20] ;Load the SWI handler offset
598 cmp r14,#0 ;Does this look sensible?
599 beq loop ;No -- loop round for more
600
601 ; --- Add the menu item for this module ---
602
603 ldr r14,[r3,#&10] ;Load the module name offset
604 add r14,r3,r14 ;Add this on to the base
605 stmia r7!,{r3,r14} ;Store base and name string
606 adr r0,sl__rfmItem ;Point to the menu block
607 adr r1,sl__rfmModule ;Point to the handler
608 sub r2,r7,#8 ;Point to name pointer
609 mov r3,r12 ;And get my workspace addr
610 bl menu_create ;Add to the current menu
611 b loop ;Keep on looping
612
613 ; --- Report an error ---
614
615 .sl__imRefError add r2,r0,#4 ;Point to error message
616 adr r0,FNliterr(1,"slMLE") ;Point to skeleton
617 bl str_error ;Mangle the message
618 mov r1,#1 ;Just an OK button
619 bl errorBox ;Report the message
620 ldmfd r13!,{r0-r7,pc}^ ;And return to caller
621
622 ; --- Refresh module title ---
623
624 .sl__rfmTitle FNmenu("slMDS")
625 ;FNmenu_item("slKNL") ;Not implemented
626 FNmenu_end
627
628 ; --- Refresh module items ---
629
630 .sl__rfmItem FNmenu_itemInd(4)
631 FNmenu_end
632
633 FNltorg
634
635 ; --- Quit the application ---
636
637 .sl__imQuit stmfd r13!,{r14} ;Save return address away
638 bl sl__okToQuit ;Make sure it's all right
639 swics "OS_Exit" ;Yes -- just kill everything
640 ldmfd r13!,{pc}^ ;Otherwise ignore the request
641
642 FNltorg
643
644 ; --- sl__rfmKernel ---
645 ;
646 ; On entry; --
647 ;
648 ; On exit; --
649 ;
650 ; Use; Refreshes the kernel SWIs table.
651
652 .sl__rfmKernel movs pc,r14 ;Not implemented
653
654 FNltorg
655
656 ; --- sl__rfmModule ---
657 ;
658 ; On entry; --
659 ;
660 ; On exit; --
661 ;
662 ; Use; Refreshes a particular module.
663
664 .sl__rfmModule stmfd r13!,{r0,r1,r14} ;Save link
665 ldr r0,[r10,#0] ;Load module base
666 bl sl__scanMod ;Scan the module
667 movvs r1,#1 ;If it failed
668 blvs errorBox ;Report the error
669 ldmfd r13!,{r0,r1,pc}^ ;And return to caller
670
671 FNltorg
672
673 ; --- sl__setFlags ---
674 ;
675 ; On entry; --
676 ;
677 ; On exit; --
678 ;
679 ; Use; Sets up the flags from the flex anchors we have.
680
681 .sl__setFlags stmfd r13!,{r0,r14} ;Save some registers
682 ldr r0,[r12,#sl__flags] ;Load the flags word
683 ldr r14,[r12,#sl__anchor] ;Load the block anchor
684 cmp r14,#0 ;Is that defined?
685 orrne r0,r0,#slFlag__block ;Yes -- set the flag
686 biceq r0,r0,#slFlag__block ;No -- clear it
687 tstne r0,#slFlag__format ;Is there a format chunk?
688 orrne r0,r0,#slFlag__savable ;Yes -- set savable flag
689 biceq r0,r0,#slFlag__savable ;No -- clear it then
690 str r0,[r12,#sl__flags] ;Save modified flags
691 ldmfd r13!,{r0,pc}^ ;And return to caller
692
693 FNltorg
694
695 ; --- sl__unknowns ---
696 ;
697 ; On entry; R0 == event code
698 ; R1 == pointer to event data
699 ;
700 ; On exit; CS if event interesting, else CC
701 ; R2-R10 corrupted
702 ;
703 ; Use; Handles interesting messages (e.g. PreQuit)
704
705 .sl__unknowns cmp r0,#17 ;Is this a User_Message?
706 cmpne r0,#18 ;Or a User_Message_Recorded?
707 movnes pc,r14 ;No -- ignore it then
708
709 ldr r2,[r1,#16] ;Load the event code
710 cmp r2,#8 ;Is this a pre-quit message?
711 movnes pc,r14 ;No -- not interested then
712
713 ; --- Handle a PreQuit message ---
714
715 orrs r14,r14,#C_flag ;We claim this event now
716 stmfd r13!,{r14} ;Save return address
717 bl sl__okToQuit ;Ask user if required
718 ldmcsfd r13!,{pc}^ ;If OK then continue normally
719
720 stmfd r13!,{r0-r2} ;Save some more registers
721 mov r0,r11 ;Point to scratchpad
722 ldr r2,[r1,#0] ;Load the message size
723 bl fastMove ;Copy the message data over
724 ldr r14,[r0,#8] ;Load his reference number
725 str r14,[r0,#12] ;Set this as a reply to it
726 mov r1,r0 ;Point to my copy
727 mov r0,#19 ;Send this as an acknowledge
728 ldr r2,[r1,#4] ;Load his task handle out
729 swi "Wimp_SendMessage" ;Send the message back
730 ldmfd r13!,{r0-r2,pc}^ ;Now return to caller
731
732 FNltorg
733
734 ; --- sl__okToQuit ---
735 ;
736 ; On entry; --
737 ;
738 ; On exit; CS if we're allowed to quit, else CC
739 ;
740 ; Use; Works out if we're allowed to quit the application. If it
741 ; isn't sure, it pops up a warning box and asks.
742
743 .sl__okToQuit stmfd r13!,{r0,r1,r14} ;Save some registers
744 ldr r14,[r12,#sl__flags] ;Load the flags word out
745 tst r14,#slFlag__modified ;Has the block been changed?
746 beq sl__otq90 ;No -- then skip onwards
747
748 adr r0,FNlitsz("slOTQ") ;Point to warning messae
749 bl msgs_lookup ;Translate the tag
750 adr r1,sl__quitButts ;Point to buttons block
751 bl warning ;Pop up the warning box
752 ldmfd r13!,{r0,r1,r14} ;Unstack the registers
753 orrcss pc,r14,#C_flag ;If OK, set the C flag
754 bicccs pc,r14,#C_flag ;Otherwise clear it
755
756 .sl__otq90 ldmfd r13!,{r0,r1,r14} ;Unstack the registers
757 orrs pc,r14,#C_flag ;Set C -- we're OK
758
759 .sl__quitButts FNbutton("slQUTB")
760 FNbuttons_cancel
761 FNbuttons_end
762
763 FNltorg
764
765 ;----- Save a SWI file ------------------------------------------------------
766
767 ; --- sl__fmtHandler ---
768 ;
769 ; On entry; R0 == menu event
770 ; R1 == menu item
771 ; R10 == pointer to chunk name
772 ;
773 ; On exit; --
774 ;
775 ; Use; Handles events on the save menu.
776
777 .sl__fmtHandler cmp r0,#mEvent_help ;Is this a help request?
778 beq sl__fmtHelp ;Yes -- give help then
779 cmp r0,#mEvent_subMenu ;Is this a submenu?
780 cmpne r0,#mEvent_select ;Or a click?
781 movnes pc,r14 ;No -- ignore this
782
783 stmfd r13!,{r0-r5,r14} ;Save some registers
784 ldr r0,[r12,#sl__used] ;Load the actual block size
785 ldr r1,FNlitw(&fff) ;Output as a data file
786 adr r2,FNlitsz("swis") ;Point to the dummy name
787 adr r3,sl__saveDef ;Point to handler block
788 mov r4,r10 ;Pass document handle
789 mov r5,r12 ;And pass the workspace addr
790 bl saveAs ;Try to do the save op
791 movvs r1,#1 ;If it failed, report error
792 blvs errorBox ;In a nice error box
793 ldmfd r13!,{r0-r5,pc}^ ;And return to caller
794
795 .sl__saveDef FNs ("slSVT") ;Title for the save box
796 movs pc,r14 ;Don't care when it closes
797 b sl__saveFile ;Save to a disk file
798 b sl__send ;Send to another application
799 b xsave_done ;Tell xsave it's all done
800 b sl__failed ;Tidy up after a failure
801
802 .sl__fmtHelp stmfd r13!,{r0-r2,r14} ;Save some registers
803 ldr r0,[r10,#4] ;Find the format chunk name
804 bl msgs_lookup ;Translate in case of tag
805 mov r1,r0 ;Point to the result
806 mov r0,r11 ;Point to scratchpad
807 bl str_cpy ;Copy the string over
808 .loop ldrb r14,[r0,#-1]! ;Load last byte of string
809 subs r14,r14,#ASC(".") ;Is it part of an ellipsis?
810 streqb r14,[r0,#0] ;Yes -- nobble that byte
811 beq loop ;And try again
812 adr r0,FNlitsz("slhSVF") ;Point to help message tag
813 bl msgs_lookup ;Translate the message
814 bl str_buffer ;Find an output buffer
815 mov r2,r11 ;Point to scratchpad string
816 bl str_subst ;And build the help string
817 bl help_add ;Add this to help message
818 ldmfd r13!,{r0-r2,pc}^ ;Return to caller
819
820 FNltorg
821
822 ; --- sl__saveFile ---
823 ;
824 ; On entry; R0 == pointer to file name
825 ; R1 == safe flag
826 ;
827 ; On exit; --
828 ;
829 ; Use; Saves the SWI block to a file.
830
831 .sl__saveFile stmfd r13!,{r0-r5,r14} ;Save some registers
832 mov r2,#0 ;No current name for this
833 bl sl__replace ;Do we replace the file?
834 movcc r0,#0 ;No -- return null error
835 bcc sl__sf20 ;But cancel the save op
836
837 ; --- Get on with saving the file ---
838
839 .sl__sf10 mov r3,r0 ;Look after the file name
840 adr r0,sl__writeList ;Point to saver routine
841 mov r1,r10 ;Pass it the document handle
842 mov r2,r12 ;And my workspace pointer
843 ldr r4,FNlitw(&FFF) ;Pass the filetype over
844 bl xsave_save ;Try to save the file
845 bvs sl__sf20 ;If failed, abort now
846
847 ; --- Now retrostamp the file ---
848
849 mov r0,#17 ;Read info on the file
850 mov r1,r3 ;Point to the filename
851 swi "XOS_File" ;Read info on the file
852 movvc r0,#1 ;Now we set the info
853 bicvc r2,r2,#&FF ;Leave filetype alone
854 orrvc r2,r2,#&3A ;Put in our dummy datestamp
855 ldrvc r3,FNlitw(&BD896000) ;Set up rest of datestamp
856 swivc "XOS_File" ;Now retrostamp it nicely
857 ldmvcfd r13!,{r0-r5,pc}^ ;If it worked OK, return
858
859 ; --- It failed ---
860
861 .sl__sf20 add r13,r13,#4 ;Don't restore R0 on exit
862 ldmfd r13!,{r1-r5,r14} ;Unstack saved registers
863 orrs pc,r14,#V_flag ;And return to caller
864
865 FNltorg
866
867 ; --- sl__send ---
868 ;
869 ; On entry; R2 == accumulator value (initially 0)
870 ;
871 ; On exit; R0 == pointer to block to send
872 ; R1 == size of block to send
873 ; CS if this is the last block, else CC
874 ;
875 ; Use; Sends a block of data to another application.
876
877 .sl__send adr r0,sl__writeList ;Point to my saver routine
878 mov r1,r10 ;Pass the document handle
879 mov r2,r12 ;Pass my workspace too
880 b xsave_send ;And get another block
881
882 FNltorg
883
884 ; --- sl__failed ---
885 ;
886 ; On entry; R0 == pointer to error, or 0
887 ; R1 == 1
888 ;
889 ; On exit; --
890 ;
891 ; Use; Terminates a save job, and reports an error.
892
893 .sl__failed stmfd r13!,{r0-r2,r14} ;Save some registers
894 bl xsave_failed ;Tell xsave it's finished
895 cmp r0,#0 ;Is there an actual error?
896 addne r2,r0,#4 ;Point to error text
897 adrne r0,FNliterr(1,"slSFE")
898 blne msgs_error ;Translate and substitute
899 movne r1,#1 ;Display just an OK button
900 blne errorBox ;Yes -- report it then
901 ldmfd r13!,{r0-r2,pc}^ ;Return to caller
902
903 FNltorg
904
905 ; --- sl__replace ---
906 ;
907 ; On entry; R0 == filename
908 ; R1 == safeness flag
909 ; R2 == pointer to current name, or 0
910 ;
911 ; On exit; --
912 ;
913 ; Use; CS to save, CC to cancel
914
915 .sl__replace stmfd r13!,{r0-r2,r14} ;Save some registers
916 cmp r1,#0 ;Is the file marked as safe?
917 beq sl__replace10 ;No -- then don't ask
918
919 movs r1,r2 ;Is there a current name?
920 beq sl__replace05 ;No -- can't do this check
921 bl str_icmp ;Compare the file names
922 beq sl__replace10 ;The same name -- don't ask
923
924 .sl__replace05 bl res_exists ;Does the file exist?
925 bcc sl__replace10 ;No -- then don't ask
926
927 ; --- Ask the user if this is right ---
928
929 mov r2,r0 ;Get the filename pointer
930 adr r0,FNlitsz("slRPP") ;Point to the prompt message
931 bl msgs_lookup ;Translate the message
932 bl str_buffer ;Find a handy string buffer
933 bl str_subst ;Build the prompt string
934 adr r1,sl__exWarn ;Point to the buttons def
935 bl warning ;Display the warning box
936 ldmccfd r13!,{r0-r2,r14} ;If no, abort the job
937 bicccs pc,r14,#C_flag ;Tell caller it's all off
938
939 .sl__replace10 ldmfd r13!,{r0-r2,r14} ;Restore registers
940 orrs pc,r14,#C_flag ;And let it all go ahead
941
942 .sl__exWarn FNbutton("slRPL")
943 FNbuttons_cancel
944 FNbuttons_end
945
946 FNltorg
947
948 ;----- Write out a dump file ------------------------------------------------
949
950 ; --- sl__svdDone ---
951 ;
952 ; On entry; --
953 ;
954 ; On exit; --
955 ;
956 ; Use; Handles the save box closing. We allow loads of dump files
957 ; again.
958
959 .sl__svdDone stmfd r13!,{r14} ;Save some registers
960 ldr r14,[r12,#sl__flags] ;Load the flags word
961 bic r14,r14,#slFlag__saving ;Turn off the saving flag
962 str r14,[r12,#sl__flags] ;Save the flags back
963 ldmfd r13!,{pc}^ ;And return to caller
964
965 FNltorg
966
967 ; --- sl__saveDump ---
968 ;
969 ; On entry; R0 == pointer to file name
970 ; R1 == safeness flag
971 ;
972 ; On exit; --
973 ;
974 ; Use; Saves a dump of the current SWI names
975
976 .sl__saveDump stmfd r13!,{r0-r5,r14} ;Save some registers
977 add r2,r12,#sl__dumpFile ;Point to current name
978 bl sl__replace ;Do we actually do this?
979 movcc r0,#0 ;If not, return null error
980 bcc sl__saved90 ;To cancel the save op
981
982 mov r1,r0 ;Point to the filename
983 mov r0,#10 ;Save memory as a file
984 ldr r2,FNlitw(&FFD) ;Save as a data file
985 add r14,r12,#sl__anchor ;Point to dump anchor
986 ldmia r14,{r4,r5} ;Load base and size
987 add r5,r4,r5 ;Turn size into limit
988 swi "XOS_File" ;Try to save the file
989 bvs sl__saved90 ;If it failed, abort
990
991 ldr r14,[r13,#4] ;Load the safeness flag
992 cmp r14,#0 ;Is the flag safe?
993 beq sl__saved50 ;No -- skip onwards then
994
995 ; --- Do special things when file saved properly ---
996
997 ldr r14,[r12,#sl__flags] ;Yes -- load flags then
998 bic r14,r14,#slFlag__modified ;Clear the modified bit
999 str r14,[r12,#sl__flags] ;And store the flags back
1000
1001 bl sl__setDumpName ;Go and set the name
1002
1003 .sl__saved50 ldmfd r13!,{r0-r5,pc}^ ;Return to caller
1004
1005 .sl__saved90 add r13,r13,#4 ;Don't restore R0 on exit
1006 ldmfd r13!,{r1-r5,r14} ;Restore registers
1007 orrs pc,r14,#V_flag ;And return with V set
1008
1009 FNltorg
1010
1011 ; --- sl__sendDump ---
1012 ;
1013 ; On entry; --
1014 ;
1015 ; On exit; R0 == pointer to block to send
1016 ; R1 == size of block
1017 ; CS for last block, CC otherwise
1018 ;
1019 ; Use; Sends the SWI dump block to another application
1020
1021 .sl__sendDump add r0,r12,#sl__anchor ;Find the anchor block
1022 ldmia r0,{r0,r1} ;Load the values out
1023 orrs pc,r14,#C_flag ;And return the only block
1024
1025 FNltorg
1026
1027 ; --- sl__svdFail ---
1028 ;
1029 ; On entry; R0 == pointer to error, or 0
1030 ; R1 == 1
1031 ;
1032 ; On exit; --
1033 ;
1034 ; Use; Terminates a save job, and reports an error.
1035
1036 .sl__svdFail stmfd r13!,{r0-r2,r14} ;Save some registers
1037 cmp r0,#0 ;Is there an actual error?
1038 addne r2,r0,#4 ;Point to error text
1039 adrne r0,FNliterr(1,"slSDE")
1040 blne msgs_error ;Translate and substitute
1041 movne r1,#1 ;Display just an OK button
1042 blne errorBox ;Yes -- report it then
1043 ldmfd r13!,{r0-r2,pc}^ ;Return to caller
1044
1045 FNltorg
1046
1047 ;----- Writing out a list of SWIs -------------------------------------------
1048
1049 ; --- sl__writeList ---
1050 ;
1051 ; On entry; --
1052 ;
1053 ; On exit; --
1054 ;
1055 ; Use; Writes the list of SWIs to the current xsave output.
1056
1057 .sl__writeList stmfd r13!,{r0-r10,r14} ;Save some registers
1058
1059 ; --- Make sure we can do this ---
1060
1061 ldr r14,[r12,#sl__anchor] ;Load the block anchor
1062 cmp r14,#0 ;Is it created currently?
1063 adreq r0,FNliterr(1,"slNSS")
1064 bleq msgs_error ;Translate the error
1065 beq sl__wl90 ;And return the error
1066 ldr r14,[r12,#sl__format] ;Load the format anchor
1067 cmp r14,#0 ;Is it created currently?
1068 adreq r0,FNliterr(1,"slNFD")
1069 bleq msgs_error ;Translate the error
1070 beq sl__wl90 ;And return the error
1071
1072 ; --- Get on with saving then ---
1073
1074 swi "Hourglass_On" ;Start an hourglass going
1075
1076 ; --- Set up initial registers ---
1077
1078 ldr r9,[r10,#0] ;Load the block base
1079 mov r0,r10 ;Point to the anchor
1080 bl flex_size ;Get the block size
1081 add r10,r9,r0 ;Find the format limit
1082 adr r8,FNlitsz("*UNDEFINED*") ;No module name defined yet
1083 mov r7,r8 ;No prefix string yet either
1084 mov r6,r8 ;And no actual SWI name
1085 mvn r5,#NOT(-1) ;No SWI number defined either
1086
1087 ; --- Write out the preamble ---
1088
1089 bl sl__doString ;Write out this format
1090 bvs sl__wl90 ;If it failed, bail out
1091
1092 ; --- We've found the module header ---
1093 ;
1094 ; Now we set up for the main loop, by remembering the index
1095 ; into the format string; we then embark on the first item
1096 ; in the SWI list.
1097
1098 mov r4,r9 ;Remember this position
1099 ldr r3,[r12,#sl__anchor] ;Load the anchor base address
1100 mov r2,#0 ;Start at the beginning
1101
1102 ; --- The main output loop ---
1103
1104 .sl__wl15 add r1,r3,r2 ;Work out address of block
1105 ldr r5,[r1,#4] ;Load the SWI chunk number
1106 bic r5,r5,#&ff000000 ;Clear the flags bits
1107 add r8,r1,#8 ;Point to the module name
1108 mov r9,r4 ;Start from preamble position
1109 bl sl__doString ;Write out this format string
1110 bvs sl__wl90 ;If it failed, bail out
1111
1112 ; --- Written the header -- now do the SWIs ---
1113
1114 mov r2,r9 ;Remeber format index
1115 mov r7,r8 ;Work out prefix string pos
1116 .sl__wl20 ldrb r14,[r7],#1 ;Load next byte
1117 cmp r14,#0 ;Is this end of module name?
1118 bne sl__wl20 ;No -- keep going round
1119
1120 mov r6,r7 ;Work out SWI name position
1121 .sl__wl25 ldrb r14,[r6],#1 ;Load next byte from string
1122 cmp r14,#0 ;Is this the end yet?
1123 bne sl__wl25 ;No -- keep going
1124 .sl__wl26 ldrb r14,[r6,#0] ;Load the first byte
1125 cmp r14,#0 ;Is it a null string?
1126 beq sl__wl30 ;Yes -- move on to next mod
1127 cmp r14,#1 ;Is this a dummy SWI?
1128 addeq r6,r6,#1 ;Yes -- move pointer on
1129 addeq r5,r5,#1 ;And move on the SWI counter
1130 beq sl__wl26 ;And start again
1131
1132 mov r9,r2 ;Point to format string
1133 bl sl__doString ;Write this string out
1134 bvs sl__wl90 ;If it failed, bail out
1135 add r5,r5,#1 ;Bump up the SWI number
1136 b sl__wl25 ;And go round for more
1137
1138 ; --- Finished a module ---
1139
1140 .sl__wl30 ldr r2,[r1,#0] ;Load the size word
1141 sub r14,r1,r3 ;Work out old offset
1142 add r2,r14,r2 ;Add it onto previous offset
1143 ldr r14,[r12,#sl__used] ;Load current size of block
1144 cmp r2,r14 ;Is this the last one?
1145 bcc sl__wl15 ;No -- do this module too
1146
1147 ; --- Do the end bit of the file ---
1148
1149 bl sl__doString ;Write out the postamble
1150 bvs sl__wl90 ;If it failed, bail out
1151
1152 swi "Hourglass_Off" ;Turn off the hourglass
1153 ldmfd r13!,{r0-r10,pc}^ ;Return to caller
1154
1155 ; --- It failed -- return an error
1156
1157 .sl__wl90 swi "Hourglass_Off" ;Turn off the hourglass
1158 add r13,r13,#4 ;Don't restore R0
1159 ldmfd r13!,{r1-r10,r14} ;Restore registers
1160 orrs pc,r14,#V_flag ;And return the error
1161
1162 FNltorg
1163
1164 ; --- sl__doString ---
1165 ;
1166 ; On entry; R5 == current SWI number
1167 ; R6 == pointer to current SWI postfix
1168 ; R7 == pointer to current SWI prefix
1169 ; R8 == pointer to current module name
1170 ; R9 == pointer to format string input
1171 ; R10 == pointer to end of format string
1172 ;
1173 ; On exit; R1, R2, R4 and R6-R10 may be flex relocated
1174 ; R0 corrupted
1175 ; R9 == pointer to format string when processing stopped
1176 ; May return an error
1177 ;
1178 ; Use; Outputs a string, based on a format with the following
1179 ; syntax:
1180 ;
1181 ; All characters are echoed directly except `%' which is
1182 ; an escape for the following character. Escape codes defined
1183 ; are:
1184 ;
1185 ; %s == current SWI name
1186 ; %m == current module name
1187 ; %n == current SWI number
1188 ; %x == current X SWI number (i.e. SWI number OR &20000)
1189 ; %% == end of formatting section
1190
1191 .sl__doString stmfd r13!,{r3,r14} ;Save some registers
1192 FNflex_save("r1,r2,r4") ;Save caller's registers
1193 sub r13,r13,#128 ;Make a small buffer
1194 orr r3,r5,#&20000 ;Get the X version number
1195
1196 .sl__dostr10 cmp r9,r10 ;Are we at the end yet?
1197 bcs sl__dostr50 ;Yes -- return then
1198 ldrb r0,[r9],#1 ;Load next byte from string
1199 cmp r0,#ASC("%") ;Is this a magic `%' sign?
1200 beq sl__dostr20 ;Yes -- do clever things
1201
1202 bl sl__byte ;Write this byte out
1203 b sl__dostr10 ;And continue formatting
1204
1205 ; --- Handle an escape character ---
1206
1207 .sl__dostr20 ldrb r0,[r9],#1 ;Load next byte from string
1208 orr r0,r0,#&20 ;Make sure char is lowercase
1209 cmp r0,#ASC("s") ;Is this a SWI name?
1210 adreq r0,FNlitsz("%5_%4") ;Yes -- point to skeleton
1211 cmp r0,#ASC("m") ;Or the module name?
1212 adreq r0,FNlitsz("%6") ;Yes -- point to skeleton
1213 cmp r0,#ASC("n") ;Or the SWI number?
1214 adreq r0,FNlitsz("%x3") ;Yes -- point to skeleton
1215 cmp r0,#ASC("x") ;Or the SWI X number?
1216 adreq r0,FNlitsz("%x1") ;Yes -- point to skeleton
1217 cmp r0,#ASC("d") ;Or a date string?
1218 beq sl__dostr40 ;Yes -- process specially
1219 cmp r0,#ASC("p") ;Or a literal percent?
1220 adreq r0,FNlitsz("%%") ;Yes -- point to skeleton
1221 cmp r0,#ASC("%") ;Or a percent sign?
1222 addeq r9,r9,#1 ;Yes -- skip a newline char
1223 beq sl__dostr50 ;Yes -- handle that
1224
1225 cmp r0,#256 ;Do we have an address?
1226 bcc sl__dostr10 ;No -- go round for more then
1227
1228 mov r1,r13 ;Build string in it
1229 bl str_subst ;Build output string
1230 mov r2,r0 ;Point to the string
1231 .sl__dostr30 ldrb r0,[r2],#1 ;Load next byte
1232 cmp r0,#32 ;Is it the terminator?
1233 blcs sl__byte ;No -- output it then
1234 bcs sl__dostr30 ;And loop back round again
1235 b sl__dostr10 ;Carry on with the string
1236
1237 FNltorg
1238
1239 ; --- Handle a date format string ---
1240
1241 .sl__dostr40 stmfd r13!,{r3} ;I need this register
1242 sub r13,r13,#8 ;Make time buffer on stack
1243 mov r14,#3 ;Get the subreason code
1244 strb r14,[r13,#0] ;Save that in the block
1245 mov r1,r13 ;Point to the buffer
1246 mov r0,#14 ;Get the main reason code
1247 swi "OS_Word" ;Read the current time
1248
1249 ldrb r0,[r9,#0] ;Load the next byte ready
1250 cmp r0,#ASC("[") ;Is this an argument?
1251 adrne r0,FNlitsz("slDFMT") ;No -- point to default
1252 blne msgs_lookup ;Translate nicely
1253 movne r3,r0 ;And put it in the right reg
1254 bne sl__dostr45 ;And skip onwards a bit
1255
1256 ; --- Read the format string argument ---
1257
1258 mov r1,r11 ;Point to a spare buffer
1259 add r9,r9,#1 ;Skip past the `[' char
1260 .a ldrb r14,[r9],#1 ;Load the next byte
1261 cmp r14,#ASC("]") ;Is that the end yet?
1262 cmpne r14,#&0D ;Check return for safety
1263 moveq r14,#0 ;Yes -- terminate string
1264 strb r14,[r1],#1 ;Store the byte away
1265 bne a ;Loop until all done
1266 mov r3,r11 ;Point to the format string
1267
1268 ; --- Now read the actual string ---
1269
1270 .sl__dostr45 mov r0,r13 ;Point to the time block
1271 add r1,r13,#12 ;Point to output buffer
1272 mov r2,#128 ;Get the buffer size
1273 swi "OS_ConvertDateAndTime" ;Translate the string
1274 add r13,r13,#8 ;Don't need the time any more
1275 ldmfd r13!,{r3} ;Restore register I saved
1276 mov r2,r13 ;Point to buffer start
1277 b sl__dostr30 ;Now output this string
1278
1279 ; --- Finished reading the input ---
1280
1281 .sl__dostr50 add r13,r13,#128 ;Reclaim my little buffer
1282 FNflex_load("r1,r2,r4") ;Restore caller's pointers
1283 ldmfd r13!,{r3,r14} ;Restore other registers
1284 bics pc,r14,#V_flag ;Return without an error
1285
1286 ; --- Write byte in R0 to output ---
1287
1288 .sl__byte mov r1,r14 ;Look after return address
1289 FNflex_save("r6-r10") ;Save lots of values
1290 bl xsave_byte ;Write this byte out
1291 FNflex_load("r6-r10") ;Restore our registers
1292 movvcs pc,r1 ;If OK, return to caller
1293
1294 add r13,r13,#128 ;Reclaim my little buffer
1295 FNflex_load("r1,r2,r4") ;Restore caller's pointers
1296 ldmfd r13!,{r3,r14} ;Restore other registers
1297 orrs pc,r14,#V_flag ;And return the error
1298
1299 FNltorg
1300
1301 ;----- Loading modules ------------------------------------------------------
1302
1303 ; --- sl__loadMod ---
1304 ;
1305 ; On entry; R1 == pointer to filename
1306 ;
1307 ; On exit; May return an error
1308 ;
1309 ; Use; Loads a module and adds its SWIs to the current list.
1310
1311 .sl__loadMod stmfd r13!,{r0-r2,r14} ;Save some registers
1312 add r2,r12,#sl__module ;Point to anchor for this
1313 bl load_file ;Try to load the file
1314 strvs r0,[r13,#0] ;If failed, return error
1315 ldmfd r13!,{r0-r2,pc} ;Return to caller
1316
1317 FNltorg
1318
1319 ; --- sl__ibMod ---
1320 ;
1321 ; On entry; R1 == estimated file size
1322 ;
1323 ; On exit; May return an error
1324 ;
1325 ; Use; Sets up a buffer for RAM loading.
1326
1327 .sl__ibMod add r2,r12,#sl__module ;Point to anchor
1328 b load_initBuf ;Start the load op
1329
1330 FNltorg
1331
1332 ; --- sl__doneMod ---
1333 ;
1334 ; On entry; --
1335 ;
1336 ; On exit; --
1337 ;
1338 ; Use; Adds a module to the SWI list.
1339
1340 .sl__doneMod stmfd r13!,{r0-r2,r14} ;Save some registers
1341 ldr r0,[r12,#sl__module] ;Load the flex anchor
1342 bl sl__scanMod ;Scan the module
1343 bvs sl__doneMod50 ;If it failed, quit now
1344 add r0,r12,#sl__module ;Point to the anchor
1345 bl flex_free ;Free the block
1346 ldmfd r13!,{r0-r2,pc}^ ;And return to caller
1347
1348 .sl__doneMod50 add r2,r0,#4 ;Look after the error
1349 add r0,r12,#sl__module ;Point to the anchor
1350 bl flex_free ;Free the block
1351 adr r0,FNliterr(1,"slMAA")
1352 bl msgs_error ;Translate and substitute
1353 mov r1,#1 ;Only have one button
1354 bl errorBox ;Report the error
1355 ldmfd r13!,{r0-r2,pc}^ ;And return to caller
1356
1357 FNltorg
1358
1359 ; --- sl__lfMod ---
1360 ;
1361 ; On entry; R0 == pointer to error
1362 ; R1 == 1
1363 ;
1364 ; On exit; --
1365 ;
1366 ; Use; Reports an error when an attemt to load a module failed.
1367
1368 .sl__lfMod stmfd r13!,{r0-r2,r14} ;Save some registers
1369 cmp r0,#0 ;Is there a real error?
1370 addne r2,r0,#4 ;Point to error text
1371 adrne r0,FNliterr(1,"slLFM")
1372 blne msgs_error ;Translate and substitute
1373 movne r1,#1 ;Only use one button
1374 blne errorBox ;Report the error
1375 ldmfd r13!,{r0-r2,pc}^ ;And return to caller
1376
1377 FNltorg
1378
1379 ;----- Loading dump files ---------------------------------------------------
1380
1381 ; --- sl__loadDmp ---
1382 ;
1383 ; On entry; R1 == pointer to filename
1384 ;
1385 ; On exit; May return an error
1386 ;
1387 ; Use; Loads a module and adds its SWIs to the current list.
1388
1389 .sl__loadDmp stmfd r13!,{r0-r2,r14} ;Save some registers
1390 add r0,r12,#sl__anchor ;Point to the anchor
1391 ldr r14,[r12,#sl__anchor] ;Load the current anchor
1392 cmp r14,#0 ;Is it defined currently?
1393 blne flex_free ;Yes -- free the block
1394 add r2,r12,#sl__anchor ;Point to anchor for this
1395 bl load_file ;Try to load the file
1396 strvs r0,[r13,#0] ;On error, return pointer
1397 ldmfd r13!,{r0-r2,pc} ;And return to caller
1398
1399 FNltorg
1400
1401 ; --- sl__ibDmp ---
1402 ;
1403 ; On entry; R1 == estimated file size
1404 ;
1405 ; On exit; May return an error
1406 ;
1407 ; Use; Sets up a buffer for RAM loading.
1408
1409 .sl__ibDmp stmfd r13!,{r0,r14} ;Save some registers
1410 add r0,r12,#sl__anchor ;Point to the anchor
1411 ldr r14,[r12,#sl__anchor] ;Load the current anchor
1412 cmp r14,#0 ;Is it defined currently?
1413 blne flex_free ;Yes -- free the block
1414 ldmfd r13!,{r0,r14} ;Unstack the registers
1415 add r2,r12,#sl__anchor ;Point to anchor
1416 b load_initBuf ;Start the load op
1417
1418 FNltorg
1419
1420 ; --- sl__doneDmp ---
1421 ;
1422 ; On entry; R0 == pointer to `filename'
1423 ;
1424 ; On exit; --
1425 ;
1426 ; Use; Handles a completed load of a dump file.
1427
1428 .sl__doneDmp stmfd r13!,{r0,r1,r14} ;Save some registers
1429 mov r1,r0 ;Point to the file's name
1430 bl sl__setDumpName ;Set the name up correctly
1431 add r0,r12,#sl__anchor ;Point to the anchor block
1432 bl flex_size ;Read the block's size
1433 str r0,[r12,#sl__used] ;Save the size as used value
1434 str r0,[r12,#sl__size] ;And as the size value
1435 ldr r14,[r12,#sl__flags] ;Load the flags word
1436 bic r14,r14,#slFlag__modified ;Got it from someone else
1437 str r14,[r12,#sl__flags] ;Store the flags back
1438 bl sl__setFlags ;Reset the flags nicely
1439 ldmfd r13!,{r0,r1,pc}^ ;Return to caller
1440
1441 FNltorg
1442
1443 ; --- sl__lfDmp ---
1444 ;
1445 ; On entry; R0 == pointer to error
1446 ; R1 == 1
1447 ;
1448 ; On exit; --
1449 ;
1450 ; Use; Reports an error when an attemt to load a module failed.
1451
1452 .sl__lfDmp stmfd r13!,{r0-r2,r14} ;Save some registers
1453 bl sl__setFlags ;Update the flags
1454 cmp r0,#0 ;Is there a real error?
1455 addne r2,r0,#4 ;Point to error text
1456 adrne r0,FNliterr(1,"slLFM")
1457 blne msgs_error ;Translate and substitute
1458 movne r1,#1 ;Only use one button
1459 blne errorBox ;Report the error
1460 ldmfd r13!,{r0-r2,pc}^ ;And return to caller
1461
1462 FNltorg
1463
1464 ;----- Format of the SWI table ----------------------------------------------
1465 ;
1466 ; In order to speed things up, we maintain a table of SWI names in memory,
1467 ; and write this out to a file when the user wants us to. This also means
1468 ; that we can build up a list of SWIs over a period of time, by the user
1469 ; dropping module files onto our icon or window -- this saves having to load
1470 ; large numbers of modules into the RMA.
1471 ;
1472 ; The format is fairly simple. We keep a linked list of module blocks in
1473 ; a flex block. The blocks are sorted by ascending order of SWI chunk base
1474 ; numbers. Each module block looks like this;
1475 ;
1476 ; word; size of this link block
1477 ; word; SWI chunk base number for module and flags in top 8 bits
1478 ; string; name of module which provides these SWIs (null-terminated)
1479 ; string; SWI prefix for following SWI names (null-terminated)
1480 ; string; name of first SWI provided by module (null-terminated)
1481 ; string; name of second SWI provided by module (null-terminated)
1482 ; ... ...
1483 ; string; name of last SWI provided by module (null-terminated)
1484 ; byte; 0 (list terminator)
1485 ; align; to word boundary
1486
1487 ; --- sl__setDumpName ---
1488 ;
1489 ; On entry; R1 == 0 for default `SWIDump' or pointer to name
1490 ;
1491 ; On exit; --
1492 ;
1493 ; Use; Sets the name of the current dump file.
1494
1495 .sl__setDumpName stmfd r13!,{r0-r2,r14} ;Save some registers
1496 movs r0,r1 ;Point to the source string
1497 adreq r0,FNlitsz("SWIDump") ;No string -- use default
1498 add r1,r12,#sl__dumpFile ;Point to the name buffer
1499 mov r2,#256 ;The buffer size
1500 orr r2,r2,#&C0000000 ;Don't do `|'s or `""'s
1501 swi "OS_GSTrans" ;Expand system variables
1502 ldmfd r13!,{r0-r2,pc}^ ;And return to caller
1503
1504 FNltorg
1505
1506 ; --- sl__initBlock ---
1507 ;
1508 ; On entry; --
1509 ;
1510 ; On exit; May return an error
1511 ;
1512 ; Use; Initialises the SWI list block with the currently recognised
1513 ; OS SWIs.
1514
1515 .sl__initBlock stmfd r13!,{r0-r3,r14} ;Save some registers
1516
1517 add r0,r12,#sl__anchor ;Point to the anchor
1518 ldr r14,[r12,#sl__anchor] ;Load the current anchor
1519 cmp r14,#0 ;Is it defined currently?
1520 blne flex_free ;Yes -- free the block
1521
1522 ; --- Reset the dump file name ---
1523
1524 mov r1,#0 ;Use the default name
1525 bl sl__setDumpName ;Go and do that please
1526
1527 ; --- Create the flex block ---
1528
1529 mov r1,#1024 ;Initially make it 1K
1530 bl flex_alloc ;Allocate the block
1531 blcs alloc_error ;If it failed, get an error
1532 bcs sl__initBlk90 ;And abort now
1533
1534 mov r14,r1 ;Get the size created
1535 mov r1,#0 ;Start output at beginning
1536 stmib r0,{r1,r14} ;Store sizes after anchor
1537
1538 ; --- Now build the kernel SWIs ---
1539 ;
1540 ; First do OS_WriteI. Then we do the kernel SWIs lower than
1541 ; &100.
1542
1543 adr r0,FNlitsz("Kernel") ;Point to string `Kernel'
1544 adr r1,FNlitsz("OS") ;Point to string `OS'
1545 mov r2,#&100 ;Get SWI chunk number
1546 bl sl__newLink ;Add in a new link block
1547 bvs sl__initBlk89 ;If it failed, stop going
1548 bcs sl__initBlk05 ;If already done, skip
1549 add r0,r12,#sl__anchor ;Point to the anchor
1550 adr r1,FNlitsz("WriteI") ;Point to string `WriteI'
1551 bl sl__string ;Add it to the block
1552 blvc sl__endLink ;Terminate this link
1553 bvs sl__initBlk89 ;If it failed, stop going
1554
1555 ; --- Now do the kernel SWIs ---
1556
1557 .sl__initBlk05 adr r0,FNlitsz("Kernel") ;Point to string `Kernel'
1558 adr r1,FNlitsz("OS") ;Point to string `OS'
1559 mov r2,#&0 ;Get SWI chunk number
1560 bl sl__newLink ;Add in a new link block
1561 bvs sl__initBlk89 ;If it failed, stop going
1562 bcs sl__initBlk17 ;Already there -- skip on
1563 mov r3,#0 ;Start at SWI number 0
1564
1565 .sl__initBlk10 mov r0,r3 ;Get the SWI number
1566 mov r1,r11 ;Build string in scratchpad
1567 mov r2,#256 ;And give the block size
1568 swi "OS_SWINumberToString" ;Read the SWI name
1569 swi "XOS_SWINumberFromString" ;Try to convert back
1570 cmp r0,r3 ;Is this what we expected?
1571 bne sl__initBlk13 ;No -- skip to end of loop
1572
1573 add r0,r12,#sl__anchor ;Point to the anchor
1574 add r1,r11,#3 ;Skip past `OS_' prefix
1575 bl sl__string ;Add it to the list
1576 bvs sl__initBlk89 ;If it failed, stop going
1577 b sl__initBlk15 ;Skip past the next bit
1578
1579 .sl__initBlk13 add r0,r12,#sl__anchor ;Point to the anchor
1580 mov r1,#1 ;Want one extra byte
1581 bl sl__ensure ;Make sure I've got it
1582 bvs sl__initBlk89 ;If it failed, stop going
1583 mov r14,#1 ;Mark this as nonexistant
1584 strb r14,[r0],#1 ;Store it in the block
1585
1586 .sl__initBlk15 add r3,r3,#1 ;Bump the SWI number
1587 cmp r3,#&100 ;Reached the end yet?
1588 blt sl__initBlk10 ;No -- go back round then
1589
1590 ; --- Finished that; end the link block ---
1591
1592 bl sl__endLink ;Terminate the link block
1593 bvs sl__initBlk89 ;If it failed, stop going
1594
1595 ; --- Now go through the module list ---
1596
1597 .sl__initBlk17 mov r1,#0 ;Start on first module
1598 .sl__initBlk20 mov r2,#0 ;Start on first instance
1599 mov r0,#12 ;Enumerate module addresses
1600 swi "XOS_Module" ;Read next module number
1601 bvs sl__initBlk30 ;If error must have finished
1602 mov r0,r3 ;Point to module base address
1603 bl sl__scanMod ;Scan module for SWIs
1604 bvs sl__initBlk90 ;If it failed, stop going
1605 cmp r2,#0 ;Are there more instances?
1606 addne r1,r1,#1 ;Yes -- move to next module
1607 b sl__initBlk20 ;Go handle the next module
1608
1609 ; --- Finished the module list ---
1610
1611 .sl__initBlk30 bl sl__setFlags ;Reset the flags
1612 ldmfd r13!,{r0-r3,r14} ;Unstack the registers
1613 bics pc,r14,#V_flag ;And return without error
1614
1615 ; --- Something went wrong ---
1616
1617 .sl__initBlk89 mov r3,r0 ;Look after error pointer
1618 add r0,r12,#sl__anchor ;Point to the anchor
1619 bl flex_free ;Free the block
1620 mov r1,#0 ;Clear the anchor pointer
1621 str r1,[r12,#sl__anchor] ;Save it in the block
1622 bl sl__setFlags ;Reset the flags nicely
1623 mov r0,r3 ;And restore error pointer
1624
1625 .sl__initBlk90 add r13,r13,#4 ;Don't restore R0 on exit
1626 ldmfd r13!,{r1-r3,r14} ;Restore registers
1627 orrs pc,r14,#V_flag ;And return the error
1628
1629 FNltorg
1630
1631 ; --- sl__scanMod ---
1632 ;
1633 ; On entry; R0 == pointer to module
1634 ;
1635 ; On exit; May return an error
1636 ;
1637 ; Use; Scans a module, and adds its SWIs to the list.
1638
1639 .sl__scanMod stmfd r13!,{r0-r4,r14} ;Save some registers
1640 mov r3,r0 ;Look after module base
1641
1642 ; --- Make sure this module's OK ---
1643
1644 ldr r0,[r3,#16] ;Load the name offset
1645 ldr r1,[r3,#36] ;Load the SWI name table
1646 ldr r2,[r3,#28] ;And the SWI chunk number
1647 cmp r0,#256*1024 ;Make sure these are valid
1648 cmpcc r1,#256*1024 ;Both offsets please
1649 bcs sl__scanMod80 ;If not, ignore this module
1650
1651 tst r2,#&FF000000 ;Make sure SWI chunk's OK
1652 tsteq r2,#&0000003f
1653 tsteq r2,#&00020000
1654 bne sl__scanMod80 ;If not, ignore this module
1655 cmp r2,#&200 ;Is chunk in user range?
1656 bcc sl__scanMod80 ;No -- ignore this module
1657
1658 ; --- Set the file modified flag ---
1659
1660 ldr r14,[r12,#sl__flags] ;Load the flags word
1661 orr r14,r14,#slFlag__modified ;Set the flag
1662 str r14,[r12,#sl__flags] ;Save the flags back again
1663
1664 ; --- We now have a module to add ---
1665 ;
1666 ; For error recovery, we read the current block sizes, so
1667 ; we can reset them if all goes wrong.
1668
1669 add r0,r3,r0 ;Translate offset to address
1670 add r1,r3,r1 ;For both offsets
1671 add r14,r12,#sl__used ;Point to block size info
1672 ldmia r14,{r3,r4} ;Load the size counts
1673 FNflex_save("r1") ;Look after this pointer
1674 bl sl__newLink ;Add a new link in
1675 FNflex_load("r1") ;Restore pointer afterwards
1676 bvs sl__scanMod90 ;If it failed, return error
1677
1678 ; --- Now just add the SWI names in ---
1679
1680 .sl__scanMod10 ldrb r14,[r1],#1 ;Load a SWI prefix byte
1681 cmp r14,#0 ;Is this the end yet?
1682 bne sl__scanMod10 ;No -- keep on going
1683
1684 ldrb r14,[r1],#0 ;Load the next byte out
1685 cmp r14,#0 ;Is this the double-0?
1686 beq sl__scanMod15 ;Yes -- end right now
1687 add r0,r12,#sl__anchor ;Point to anchor block
1688 FNflex_save("r1") ;Save this pointer away
1689 bl sl__string ;Add string to the list
1690 FNflex_load("r1") ;Restore this pointer
1691 bvs sl__scanMod89 ;If it failed, report error
1692 b sl__scanMod10 ;Keep on adding names
1693
1694 ; --- Finished that -- wrap everything up ---
1695
1696 .sl__scanMod15 bl sl__endLink ;Terminate this block
1697 bvs sl__scanMod89 ;If it failed, tidy up
1698 .sl__scanMod80 ldmfd r13!,{r0-r4,r14} ;Restore registers
1699 bics pc,r14,#V_flag ;And return with V clear
1700
1701 ; --- Failed to do the job ---
1702
1703 .sl__scanMod89 mov r2,r0 ;Save the error pointer
1704 add r0,r12,#sl__anchor ;Point to the flex anchor
1705 mov r1,r4 ;Get the old size value
1706 bl flex_extend ;Reset the size
1707 stmib r0,{r3,r4} ;Save old index values
1708 mov r0,r2 ;Restore the error pointer
1709
1710 .sl__scanMod90 add r13,r13,#4 ;Don't restore R0 on exit
1711 ldmfd r13!,{r1-r4,r14} ;Restore the other registers
1712 orrs pc,r14,#V_flag ;And return to caller
1713
1714 FNltorg
1715
1716 ; --- sl__newLink ---
1717 ;
1718 ; On entry; R0 == pointer to module name
1719 ; R1 == pointer to SWI prefix
1720 ; R2 == SWI chunk number
1721 ;
1722 ; On exit; May return an error
1723 ;
1724 ; Use; Ensures that a link block for the given module exists. If
1725 ; it doesn't exist already, it is created at the end of the
1726 ; flex block. The index of the last link is returned, so it
1727 ; can be cleared if the actual SWI names can't be added.
1728
1729 .sl__newLink stmfd r13!,{r0-r7,r14} ;Save some registers
1730
1731 ; --- Set up for checking loop ---
1732
1733 mov r3,r0 ;Look after module name
1734 mov r4,r1 ;And the SWI prefix string
1735 FNflex_save("r1,r3") ;Save these for relocation
1736 add r14,r12,#sl__anchor ;Point to the anchor
1737 ldmia r14,{r5,r6} ;Load base and size
1738
1739 ; --- Wade on through the block ---
1740
1741 mov r7,#0 ;Start at offset 0
1742 .sl__newl10 cmp r7,r6 ;Reached the end yet?
1743 bcs sl__newl30 ;Yes -- better stop then
1744
1745 ; --- See if this is a match ---
1746
1747 add r14,r5,r7 ;Find current address
1748 ldr r0,[r14,#4] ;Load the SWI chunk number
1749 bic r0,r0,#&ff000000 ;Clear the flags byte
1750 cmp r0,r2 ;Does this match our one?
1751 bne sl__newl15 ;No -- move along then
1752
1753 add r0,r14,#8 ;Point to the module name
1754 mov r1,r3 ;Point to our module name
1755 bl str_cmp ;Compare the strings
1756 bne sl__newl15 ;No match -- move along then
1757
1758 .sl__newl13 ldrb r14,[r0],#1 ;Load module name byte
1759 cmp r14,#32 ;Is this the end?
1760 bcs sl__newl13 ;No -- keep going
1761
1762 mov r1,r4 ;Point to the SWI prefix
1763 bl str_cmp ;Do these match?
1764 beq sl__newl20 ;Yes -- remove this chunk
1765
1766 .sl__newl15 ldr r14,[r5,r7] ;Load the length of this one
1767 add r7,r7,r14 ;Move on to the next block
1768 b sl__newl10 ;And keep on going
1769
1770 ; --- Found a match -- remove a chunk ---
1771
1772 .sl__newl20 add r0,r12,#sl__anchor ;Point to the anchor
1773 ldr r2,[r5,r7] ;Get the block's size
1774 add r1,r7,r2 ;Start at the end of it
1775 rsb r2,r2,#0 ;And reduce block by this
1776 bl flex_midExtend ;Remove this chunk of data
1777 add r6,r6,r2 ;Modify the block size
1778 str r6,[r12,#sl__used] ;Save this size back
1779 ldr r14,[r12,#sl__size] ;Load the total block size
1780 add r14,r14,r2 ;Adjust that value too
1781 str r14,[r12,#sl__size] ;Store my modified value back
1782 ldr r2,[r13,#8] ;Restore caller's SWI base
1783
1784 ; --- Add a new chunk onto the block ---
1785
1786 .sl__newl30 str r6,[r12,#sl__last] ;Save the base of this block
1787 ldr r7,[r12,#sl__size] ;Get the block total size
1788
1789 add r0,r12,#sl__anchor ;Point to anchor and info
1790 mov r1,#8 ;Add in fixed size info
1791 bl sl__ensure ;Make sure there's enough
1792 strvc r2,[r0,#4] ;Save the SWI chunk number
1793
1794 addvc r0,r12,#sl__anchor ;Point to anchor and info
1795 FNflex_load("r1") ;Unstack module name pointer
1796 blvc sl__string ;Add the string in
1797 FNflex_load("r1") ;Unstack SWI prefix string
1798 blvc sl__string ;Add the string in
1799
1800 ldmvcfd r13!,{r0-r7,r14} ;Unstack registers
1801 bicvcs pc,r14,#V_flag ;And return to caller
1802
1803 ; --- It failed -- better tidy up ---
1804
1805 mov r2,r0 ;Look after error number
1806 add r0,r12,#sl__anchor ;Point to the anchor
1807 mov r1,r7 ;Get the old size back
1808 bl flex_extend ;Reset the block size
1809 stmib r0,{r6,r7} ;Save the old values back
1810 mov r0,r2 ;Get the error pointer
1811 add r13,r13,#4 ;Don't restore R0 on exit
1812 ldmfd r13!,{r1-r7,r14} ;Restore registers
1813 orrs pc,r14,#V_flag ;Return the error
1814
1815 FNltorg
1816
1817 ; --- sl__endLink ---
1818 ;
1819 ; On entry; --
1820 ;
1821 ; On exit; May return an error
1822 ;
1823 ; Use; Terminates a link block.
1824
1825 .sl__endLink stmfd r13!,{r0,r1,r14} ;Save some registers
1826 add r0,r12,#sl__anchor ;Find the flex block
1827 mov r1,#1 ;Want to add a single byte
1828 bl sl__ensure ;Make sure we've got enough
1829 bvs sl__endl90 ;If it failed, return
1830
1831 mov r14,#0 ;Get the NULL byte ready
1832 strb r14,[r0,#0] ;Save it at the end nicely
1833 add r0,r12,#sl__anchor ;Find the flex block again
1834 bl sl__align ;Word align output pointer
1835
1836 ldmia r0,{r0,r14} ;Load block base and size
1837 ldr r1,[r12,#sl__last] ;Load the offset of the block
1838 sub r14,r14,r1 ;Get the last chunk size?
1839 str r14,[r0,r1] ;Save the length word
1840
1841 ldmfd r13!,{r0,r1,r14} ;And return to caller
1842 bics pc,r14,#V_flag ;Return without error
1843
1844 .sl__endl90 add r13,r13,#4 ;Don't return R0 on exit
1845 ldmfd r13!,{r1,r14} ;Restore registers
1846 orrs pc,r14,#V_flag ;And return the error
1847
1848 FNltorg
1849
1850 ;----- Block management routines --------------------------------------------
1851
1852 ; --- sl__ensure ---
1853 ;
1854 ; On entry; R0 == pointer to anchor/size block
1855 ; R1 == number of bytes to add
1856 ;
1857 ; On exit; R0 == pointer to allocated area
1858 ; May return an error
1859 ;
1860 ; Use; Ensures that there are R1 bytes free at the end of the given
1861 ; flex block.
1862
1863 .sl__ensure stmfd r13!,{r1,r2,r14} ;Save some registers
1864 ldmib r0,{r2,r14} ;Load the base and sizes
1865 add r1,r1,r2 ;Find new total size
1866 str r1,[r0,#4] ;Save this back
1867 add r1,r1,#255 ;Align up to next 256
1868 bic r1,r1,#255 ;For niceness's sake
1869 cmp r1,r14 ;Do we already have enough
1870 bhi sl__ensure50 ;No -- allocate some more
1871 .sl__ensure10 str r1,[r0,#8] ;Save new total size
1872 ldr r0,[r0,#0] ;Load address of block
1873 add r0,r0,r2 ;Point to first free byte
1874 ldmfd r13!,{r1,r2,r14} ;Unstack registers
1875 bics pc,r14,#V_flag ;And return without error
1876
1877 .sl__ensure50 bl flex_extend ;Extend the block nicely
1878 bcc sl__ensure10 ;Rejoin program if OK
1879 bl alloc_error ;Get the error message
1880 ldmfd r13!,{r1,r2,pc} ;Return error to caller
1881
1882 FNltorg
1883
1884 ; --- sl__string ---
1885 ;
1886 ; On entry; R0 == pointer to flex block and size information
1887 ; R1 == pointer to string
1888 ;
1889 ; On exit; May return an error
1890 ;
1891 ; Use; Adds a string to a flex block.
1892
1893 .sl__string stmfd r13!,{r0-r3,r14} ;Save some registers
1894 mov r2,r0 ;Look after anchor address
1895 FNflex_save("r1") ;Save the string address
1896 mov r0,r1 ;Point to the string
1897 bl str_len ;Work out the length
1898 add r1,r0,#1 ;Get the required size
1899 mov r0,r2 ;Point to anchor and sizes
1900 bl sl__ensure ;Make sure the space is OK
1901 FNflex_load("r1") ;Restore R1 from stack
1902 blvc str_cpy ;And copy it into the block
1903 strvs r0,[r13,#0] ;Otherwise store the error
1904 ldmfd r13!,{r0-r3,pc} ;And return to caller
1905
1906 FNltorg
1907
1908 ; --- sl__align ---
1909 ;
1910 ; On entry; R0 == pointer to flex anchor and size info
1911 ;
1912 ; On exit; --
1913 ;
1914 ; Use; Word aligns the output pointer of a flex block.
1915
1916 .sl__align stmfd r13!,{r14} ;Save a register
1917 ldr r14,[r0,#4] ;Load the output offset
1918 add r14,r14,#3 ;Word align this offset
1919 bic r14,r14,#3 ;Mask off bottom bits
1920 str r14,[r0,#4] ;Store new offset back
1921 ldmfd r13!,{pc}^ ;And return to caller
1922
1923 FNltorg
1924
1925 ;----- Workspace ------------------------------------------------------------
1926 ]
1927 PROCws_start
1928
1929 sl__flags =FNws_word :REM ;Various flags bits
1930 sl__anchor =FNws_word :REM ;Flex anchor for SWI table
1931 sl__used =FNws_word :REM ;Size used in flex block
1932 sl__size =FNws_word :REM ;Actual size of flex block
1933 sl__last =FNws_word :REM ;Offset of last block
1934 sl__modNames =FNws_word :REM ;Block for module names
1935 sl__format =FNws_word :REM ;Format chunk handle
1936 sl__module =FNws_word :REM ;Anchor for loading modules
1937 sl__pollBlock =FNws (256) :REM ;Wimp_Poll data block
1938 sl__dumpFile =FNws (256) :REM ;Full pathname of dump file
1939
1940 sl__wSize =FNws (0)
1941
1942 slFlag__block = (1<<0) :REM ;We have a SWI block
1943 slFlag__format = (1<<1) :REM ;There is a format
1944 slFlag__savable = (1<<2) :REM ;We can save a SWI list
1945 slFlag__modified= (1<<3) :REM ;SWI block is unsaved
1946 slFlag__saving = (1<<4) :REM ;We're saving a dump
1947
1948 [ opt o
1949
1950 ]
1951 NEXT
1952
1953 PROCbas_aofSave
1954 END
1955
1956 REM -- Macros ---------------------------------------------------------------
1957
1958 DEF FNs(s$)
1959 [ opt 4
1960 equs s$
1961 dcb 0
1962 ]
1963 =0
1964 DEFFNP(i%):PRINT~i%:=0