chiark / gitweb /
Create readable text `.bas' for each tokenized BASIC `,ffb' file.
[ssr] / StraySrc / Sculptrix / old-vsn / s / sculptrix
1 ;
2 ; sculptrix.s
3 ;
4 ; Draws pretty 3D boxes
5 ;
6 ; © 1994 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's Sculptrix.
12 ;
13 ; Sculptrix 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 ; Sculptrix 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 Sculptrix.  If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27 ;----- Change history -------------------------------------------------------
28 ;
29 ; Version       By      Change
30 ; ~~~~~~~       ~~      ~~~~~~
31 ; 1.00          MDW     Initial version written
32 ;
33 ; 1.01          MDW     Added support for group boxes
34 ;                       Fixed validation string parser -- will now search
35 ;                       all `X' commands instead of just the first one
36 ;
37 ; 1.02          MDW     Fixed problem with multiple unslab ops in one poll
38 ;
39 ; 1.03          MDW     Stopped excessive redrawing in group box rendering
40 ;
41 ; 1.04          MDW     Done strange things to make text+sprite icons nice
42 ;                       Any contortions required are due solely to TMA.
43 ;
44 ; 1.05          MDW     Filled in group box types 0 and 2 (ridge'n'plinth)
45 ;
46 ; 1.06          MDW     Allowed user-changing of the 3D colours and things
47 ;                       Also included different colours for shaded borders
48 ;
49 ; 1.07          MDW     Fixed bug in Sculptrix_SlabIcon, which corrupted R0
50 ;                       on exit.  Nothing has been affected by this, but we
51 ;                       may as well get it right.
52 ;
53 ; 1.08          MDW     Made colour change before toggling slab on slab ops
54 ;                       Integrated colour change with toggle slab, now
55 ;                       box_toggle does all Sculptrix_DoSlab needs to, so
56 ;                       renamed box_toggle as swi_doslab.  Module therefore
57 ;                       slightly smaller!
58 ;
59 ; 1.09          TMA     Added type 7 border -- a writable type with its own
60 ;                       black border. Less flickery than a Wimp type,
61 ;                       however, the border is always 4 OS units.
62 ;
63 ;               MDW     Fixed writable border being black when it gets shaded
64 ;
65 ; 1.10          MDW     Made writable border read colours from icon, and fill
66 ;                       the whole icon with the background colour, rather
67 ;                       than just the outside.  Basically, rewrote the
68 ;                       border 7 rendering code.
69 ;
70 ; 1.11          MDW     Fixed Sculptrix_SetSpriteArea bug -- I `found' my
71 ;                       workspace twice.  Ooops.
72 ;               MDW     Changed to use new Acorn-allocated SWI chunk number
73 ;
74 ; 1.12          MDW     Improved shaded-icon checking to avoid branch.
75 ;                       Added 10cs delay to unslab with window open in line
76 ;                       with STASIS requirements.
77 ;
78 ; 1.13          MDW     Fixed bug in mitre start position -- inserted RSB
79 ;                       to make it go in the right direction.
80 ;
81 ; 1.14          MDW     Removed filling in groupbox type 0 to allow dbx
82 ;                       controls to be within group boxes.
83 ;
84 ; 1.15          MDW     Modified rendering of `xs' icons to match new STEEL
85 ;                       and Sapphire icon shading habits.  Added a 256-byte
86 ;                       static buffer for group titles, to avoid dynamic
87 ;                       allocation in mid-redraw,  Changed lots of signed
88 ;                       compares to unsigned, which removes some redundancy.
89 ;                       Fixed text+sprite handling to look in Wimp area
90 ;                       if not in user area.  Added messages support.  Added
91 ;                       border type 8 for partitions that fade properly
92 ;                       (suggested by Alex Thoukydides).
93
94 ;----- Standard header ------------------------------------------------------
95
96                 GET     libs:header
97                 GET     libs:swis
98
99                 GET     sh.messages
100                 IMPORT  s_help
101
102 ;----- PLOT code numbers ----------------------------------------------------
103
104 plot_MOVE       EQU     0
105 plot_FORE       EQU     1
106 plot_INVERSE    EQU     2
107 plot_BACK       EQU     3
108
109 plot_RELATIVE   EQU     0
110 plot_ABSOLUTE   EQU     4
111
112 plot_RECTFILL   EQU     96
113 plot_LINE       EQU     0
114
115 ;----- VDU variable numbers -------------------------------------------------
116
117 vdu_XEIG        EQU     4
118 vdu_YEIG        EQU     5
119
120 ;----- Module header --------------------------------------------------------
121
122                 AREA    |!!!Module$$Header|,CODE,READONLY
123
124                 DCD     0                       ;Module start code
125                 DCD     s_init                  ;Initialisation
126                 DCD     s_die                   ;Finalisation
127                 DCD     s_service               ;Service call
128                 DCD     s_title                 ;Module title string
129                 DCD     s_help                  ;Module help string
130                 DCD     s_command               ;Command table
131                 DCD     &4A2C0                  ;SWI chunk (temporary)
132                 DCD     s_swic                  ;SWI handling
133                 DCD     s_swin                  ;SWI names table
134                 DCD     0                       ;SWI names code
135
136 ;----- Module strings -------------------------------------------------------
137
138 s_title         DCB     "Sculptrix",0
139
140 ;----- SWI name table -------------------------------------------------------
141
142 s_swin          DCB     "Sculptrix",0
143
144                 DCB     "RedrawWindow",0
145                 DCB     "DoSlab",0
146                 DCB     "SlabIcon",0
147                 DCB     "UnslabIcon",0
148                 DCB     "BoundingBox",0
149                 DCB     "PlotIcon",0
150                 DCB     "PlotGroupBox",0
151                 DCB     "SetSpriteArea",0
152                 DCB     "UpdateIcon",0
153                 DCB     "SlabColour",0
154
155                 DCB     0
156
157 ;----- Command table --------------------------------------------------------
158
159 s_command       DCB     "Sculptrix_Colours",0
160                 DCD     cmd_colours
161                 DCB     0,0,1,0
162                 DCD     synt_colours
163                 DCD     help_colours
164
165                 DCB     "Sculptrix_GroupType",0
166                 DCD     cmd_group
167                 DCB     1,0,1,0
168                 DCD     synt_group
169                 DCD     help_group
170
171                 DCD     0
172
173 ;----- Initialisation and finalisation --------------------------------------
174
175 s_init          ROUT
176
177                 STMFD   R13!,{R14}              ;Stack link register nicely
178
179                 ; --- Get some workspace ---
180
181                 MOV     R0,#6                   ;Allocate workspace
182                 MOV     R3,#s_wsize             ;Make it *this* big
183                 SWI     XOS_Module              ;Get me memory
184                 LDMVSFD R13!,{PC}               ;Return if it barfed
185                 STR     R2,[R12]                ;Stash the workspace pointer
186                 MOV     R12,R2                  ;Move the pointer across
187
188                 ; --- Set initial values ---
189
190                 BL      vdu_set                 ;Set up the graphics vars
191                 MOV     R0,#0                   ;Initial flags setting
192                 STR     R0,s_flags              ;Store in the flags word
193                 MOV     R0,#1                   ;Start using WIMP area
194                 STR     R0,s_sarea              ;Store in sprite area word
195                 MOV     R0,#&0400               ;Default colours
196                 ORR     R0,R0,R0,LSL #16        ;Propagate to top half
197                 MOV     R1,#&0200               ;Default colours
198                 ORR     R1,R1,R1,LSL #16        ;Propagate to top half
199                 MOV     R2,#&0C00
200                 ORR     R2,R2,#&000E
201                 ADR     R3,s_colours
202                 STMIA   R3,{R0-R2}
203
204                 ; --- I think that's it ---
205
206                 LDMFD   R13!,{PC}^              ;Return to caller happy
207
208                 LTORG
209
210 s_die           ROUT
211
212                 STMFD   R13!,{R11,R14}
213                 MOV     R11,R12                 ;Keep the private word ptr
214                 LDR     R12,[R12]               ;Find my workspace
215
216                 ; --- Free my workspace ---
217
218                 MOV     R0,#7                   ;Free RMA space
219                 MOV     R2,R12                  ;Point to workspace
220                 SWI     XOS_Module              ;Try to free the memory
221                 MOV     R0,#0                   ;Gonna zero the private word
222                 STR     R0,[R11]                ;Then zero it
223                 LDMFD   R13!,{R11,PC}^          ;A happy bunny
224
225                 LTORG
226
227 ;----- Service call handling ------------------------------------------------
228
229 s_service       ROUT
230
231                 CMP     R1,#&46                 ;Is it a mode change?
232                 MOVNES  PC,R14                  ;No -- return
233
234                 LDR     R12,[R12]               ;Get my workspaxe
235                 B       vdu_set                 ;Set up the VDU variables
236
237
238 ;----- Command handlers -----------------------------------------------------
239
240 ; --- Sculptrix_Colours ---
241
242 cmd_colours     ROUT
243
244                 STMFD   R13!,{R1-R5,R14}        ;Save some registers
245                 LDR     R12,[R12]               ;Locate my workspace pointer
246
247                 ; --- If no argument, use the default ---
248
249                 CMP     R1,#0                   ;Is there an argument?
250                 ADREQ   R0,cmd__defCol          ;No -- point to default
251
252                 ; --- Read normal 3D colours ---
253
254                 LDRB    R2,[R0],#1              ;Get the first digit
255                 BL      %50cmd_colours          ;Convert to binary
256                 MOV     R3,R2,LSL #8            ;Look after it
257                 LDRB    R2,[R0],#1              ;Get the next digit
258                 BL      %50cmd_colours          ;Convert to binary
259                 ORR     R3,R3,R2                ;Mix into the word nicely
260                 ORR     R3,R3,R3,LSL #16        ;Propagate to upper half
261
262                 ; --- Read shaded 3D colours ---
263
264                 LDRB    R2,[R0],#1              ;Get the first digit
265                 BL      %50cmd_colours          ;Convert to binary
266                 MOV     R4,R2,LSL #8            ;Look after it
267                 LDRB    R2,[R0],#1              ;Get the next digit
268                 BL      %50cmd_colours          ;Convert to binary
269                 ORR     R4,R4,R2                ;Mix into the word nicely
270                 ORR     R4,R4,R4,LSL #16        ;Propagate to upper half
271
272                 ; --- Read the other colours ---
273
274                 LDRB    R2,[R0],#1              ;Get a digit
275                 BL      %50cmd_colours          ;Convert to binary
276                 MOV     R5,R2,LSL #8            ;Look after it
277                 LDRB    R2,[R0],#1              ;Get a digit
278                 BL      %50cmd_colours          ;Convert to binary
279                 ORR     R5,R5,R2                ;Look after it
280
281                 ; --- Now store these away nicely ---
282
283                 ADR     R1,s_colours            ;Point to base address
284                 STMIA   R1,{R3-R5}              ;Store them in workspace
285                 LDMFD   R13!,{R1-R5,PC}^        ;Return to caller
286
287                 ; --- Convert R2 to binary ---
288
289 50cmd_colours   SUBS    R2,R2,#'0'              ;Convert a digit
290                 CMP     R2,#10                  ;Is this bigger than 9?
291                 SUBCS   R2,R2,#7                ;Yes -- convert from upper
292                 CMP     R2,#16                  ;Still out of range?
293                 SUBCS   R2,R2,#&20              ;Yes -- must have been lower
294                 CMP     R2,#16                  ;Still out of range?
295                 BCS     %51cmd_colours          ;Yes -- that's an error
296                 MOVS    PC,R14                  ;Return to caller
297
298 51cmd_colours   ADRL    R0,msg_errBadHex        ;Point to error message
299                 LDMFD   R13!,{R1-R5,R14}        ;Unstack the registers
300                 ORRS    PC,R14,#V_flag          ;Return to caller
301
302 cmd__defCol     DCB     "4020CE",0
303
304                 LTORG
305
306 ; --- Sculptrix_GroupType ---
307
308 cmd_group       ROUT
309
310                 LDRB    R0,[R0]                 ;Get the digit
311                 LDR     R12,[R12]               ;Find my workspace
312                 LDR     R1,s_flags              ;Load my flags word
313                 BIC     R1,R1,#s_CHANNEL :OR: s_FAINTCHAN
314                 CMP     R0,#'1'                 ;Is it a deep channel?
315                 ORREQ   R1,R1,#s_CHANNEL
316                 CMP     R0,#'2'                 ;Is it a shallow channel?
317                 ORREQ   R1,R1,#s_CHANNEL :OR: s_FAINTCHAN
318                 STR     R1,s_flags
319                 MOVS    PC,R14
320
321                 LTORG
322
323 ;----- SWI names and numbers etc --------------------------------------------
324
325 s_swic          ROUT
326
327                 LDR     R12,[R12]               ;Get my workspace neatly
328                 CMP     R11,#(%01s_swic-%00s_swic)/4 ;Check SWI is in range
329                 ADDCC   PC,PC,R11,LSL #2        ;Go to correct branch instr
330                 B       %01s_swic               ;Branch to complain thing
331
332 00s_swic        B       swi_redraw
333                 B       swi_doslab
334                 B       swi_slab
335                 B       swi_unslab
336                 B       swi_bbox
337                 B       swi_ploticon
338                 B       swi_plotgroup
339                 B       swi_spritearea
340                 B       swi_update
341                 B       swi_slabcol
342
343 01s_swic        ADRL    R0,msg_errBadSwi        ;Point to error message
344                 ORRS    PC,R14,#V_flag          ;Return with an error
345
346                 LTORG
347
348 ;----- SWI handling ---------------------------------------------------------
349
350 ; --- Sculptrix_RedrawWindow ---
351 ;
352 ; R1 == pointer to redraw block
353
354 swi_redraw      ROUT
355
356                 STMFD   R13!,{R0-R11,R14}       ;Stack registers
357
358                 ; --- Find the window origin ---
359
360                 MOV     R11,R1                  ;Keep the pointer nicely
361                 BL      box_readRectangle       ;Find everything about rdrw
362
363                 ; --- Now go through the icons ---
364
365                 SUB     R13,R13,#40             ;Make way for an icon block
366                 MOV     R1,R13                  ;Point to the block
367                 LDR     R0,[R11,#0]             ;Get the window handle
368                 MOV     R2,#0                   ;Start at icon 0
369                 STMIA   R1,{R0,R2}              ;Store them in the block
370
371                 ; --- Main loop -- go through each icon and plot ---
372
373 00swi_redraw    SWI     XWimp_GetIconState      ;Read info into block
374                 ADDVS   R13,R13,#44             ;Error -- reclaim stack space
375                 LDMVSFD R13!,{R1-R11,PC}        ;And return to caller
376                 LDR     R0,[R1,#24]             ;Get the flags word
377                 CMP     R0,#1<<23               ;Is it only deleted?
378                 ADDEQ   R13,R13,#40             ;Yes -- reclaim stack space
379                 LDMEQFD R13!,{R0-R11,PC}^       ;And return to caller
380
381                 ; --- Find out whether the icon is visible ---
382
383                 ADD     R0,R1,#8                ;Point to coords block
384                 LDMIA   R0,{R0,R2-R4}           ;Load the icon coordinates
385                 CMP     R0,R7
386                 CMPLE   R2,R8
387                 CMPLE   R5,R3
388                 CMPLE   R6,R4
389                 BGT     %01swi_redraw           ;Not visible -- skip it
390
391                 ADD     R0,R1,#8                ;Point to icon block
392                 BL      box_ploticon
393
394                 ; --- Ho-hum.  Now do the next one ---
395
396 01swi_redraw    LDR     R0,[R1,#4]              ;Get the icon handle
397                 ADD     R0,R0,#1                ;Bump it up a little
398                 STR     R0,[R1,#4]              ;Store it back again
399                 B       %00swi_redraw           ;And go round for another
400
401                 LTORG
402
403 ; --- Sculptrix_DoSlab ---
404 ;
405 ; On entry:     R0 == window handle
406 ;               R1 == icon number
407 ;               R2 == colour to slab to
408 ;
409 ; On exit:      R2 == old colour of icon, or -1 if icon couldn't be slabbed
410
411 swi_doslab      ROUT
412
413                 STMFD   R13!,{R0-R11,R14}       ;Stack registers
414                 MOV     R9,R2                   ;Look after the colour
415                 MOV     R2,#-1                  ;Store -1 in stacked R2
416                 STR     R2,[R13,#8]             ;Return no colour currently
417
418                 ; --- Find out if we need to do anything ---
419
420                 SUB     R13,R13,#44             ;Make way for an icon def
421                 STMIA   R13,{R0,R1}             ;Store icon handle and stuff
422                 MOV     R1,R13                  ;Point to icon block
423                 SWI     XWimp_GetIconState      ;Get the icon information
424                 ADDVS   R13,R13,#48             ;If it failed, reclaim stack
425                 LDMVSFD R13!,{R1-R11,PC}        ;And return the error
426
427                 MOV     R3,#0                   ;Start from the beginning
428 90swi_doslab    ADD     R0,R1,#8                ;Point to actual icon def
429                 MOV     R2,#'X'                 ;Get the validation command
430                 BL      box_findValid           ;Find the validation string
431                 CMP     R2,#0                   ;Did it work?
432                 ADDEQ   R13,R13,#44             ;No -- reclaim used stack
433                 LDMEQFD R13!,{R0-R11,PC}^       ;And return to caller
434
435                 ; --- Get the border type -- only 0 and 2 slab ---
436
437                 LDRB    R0,[R2,#1]              ;Get the border type number
438                 CMP     R0,#'0'                 ;Is it a normal action type?
439                 CMPNE   R0,#'2'                 ;Or a default action type?
440                 MOVNE   R3,R2                   ;No -- point to this place
441                 BNE     %90swi_doslab           ;And loop back
442
443                 ; --- It's a worthwhile icon ---
444
445                 LDMIA   R1,{R0,R1}              ;Load window and icon handles
446                 MOV     R8,R2                   ;Look after this pointer
447                 MOV     R2,R9                   ;Get the colour wanted
448                 BL      box_setcolour           ;Set the colour properly
449                 STR     R2,[R13,#44+8]          ;Store it nicely away again
450                 MOV     R1,R13                  ;Point at the block again
451
452                 ; --- Update the border ---
453
454                 LDRB    R0,[R8,#0]              ;Get the border command
455                 EOR     R0,R0,#&20              ;Toggle its case
456                 STRB    R0,[R8,#0]              ;Store it back again
457
458                 LDR     R3,[R1,#24]             ;Load the icon flags
459                 EOR     R3,R3,#&005F0000        ;Toggle ESG and shaded bit
460                 TST     R3,#1<<22               ;Is the icon shaded?
461                 TSTNE   R3,#&001F0000           ;No -- test the ESG bits
462                 ADRNE   R11,s_colours           ;No -- use normal colours
463                 ADREQ   R11,s_shadeCols         ;Yes -- use shaded colours
464
465                 TST     R0,#&20                 ;Is it set now?
466                 ADDEQ   R11,R11,#1              ;No -- use offset colours
467
468                 ADD     R0,R1,#8                ;Point to icon def again
469                 LDMIA   R0,{R3-R6}              ;Get icon coords
470                 SUB     R3,R3,#4                ;Make space for border around
471                 SUB     R4,R4,#4
472                 ADD     R5,R5,#4
473                 ADD     R6,R6,#4
474                 STMIB   R1,{R3-R6}              ;That's now our update block
475                 SWI     XWimp_UpdateWindow      ;Try and update it then
476                 BVS     %01swi_doslab           ;If it failed skip this bit
477                 CMP     R0,#0                   ;Is there anything to do?
478                 BEQ     %01swi_doslab           ;No -- skip it too
479
480                 ADD     R2,R1,#16               ;Point to y1
481                 LDMIA   R2,{R8-R10}             ;Get coordinates from block
482                 SUB     R10,R8,R10              ;Get y origin position
483                 LDR     R8,[R2,#-12]            ;Get x0 value from block
484                 SUB     R9,R8,R9                ;Get x origin position
485
486                 ADD     R3,R3,#4                ;Point back to the icon block
487                 ADD     R3,R3,R9
488                 ADD     R4,R4,#4
489                 ADD     R4,R4,R10
490                 SUB     R5,R5,#4
491                 ADD     R5,R5,R9
492                 SUB     R6,R6,#4
493                 ADD     R6,R6,R10
494
495 00swi_doslab    ; --- Draw box (inline copy) ---
496                 ;
497                 ; We only draw the inner slabbed bit -- the rest doesn't
498                 ; change even in the default type.
499
500                 ADD     R2,R1,#4
501                 STMIA   R2,{R3-R6}              ;Store adjusted coords away
502
503                 LDRB    R0,[R11,#0]
504                 SWI     XWimp_SetColour
505                 MOV     R0,R2
506                 BL      prim_left
507                 LDRB    R0,[R11,#1]
508                 SWI     XWimp_SetColour
509                 MOV     R0,R2
510                 BL      prim_right
511                 BL      prim_bottom
512                 LDRB    R0,[R11,#0]
513                 SWI     XWimp_SetColour
514                 MOV     R0,R2
515                 BL      prim_top
516
517                 ; --- Get another rectangle ---
518
519                 SWI     XWimp_GetRectangle
520                 CMP     R0,#0                   ;Have we anything to do?
521                 BNE     %00swi_doslab           ;Yes -- do it then, dummy
522
523 01swi_doslab    ADD     R13,R13,#44
524                 LDMFD   R13!,{R0-R11,PC}^
525
526                 LTORG
527
528 ; --- Sculptrix_SlabIcon ---
529 ;
530 ; On entry:     R0 == window handle
531 ;               R1 == icon handle
532 ;               R2 == pointer to 4 word slab descriptor to be filled in
533 ; On exit:      --
534
535 swi_slab        ROUT
536
537                 STMFD   R13!,{R0-R2,R10,R14}    ;Keep link register safe
538
539                 ; --- Fill in the caller's descriptor block ---
540
541                 MOV     R10,R2                  ;Keep the pointer safe
542                 STMIA   R10,{R0,R1}             ;Stash the icon info away
543                 SWI     XOS_ReadMonotonicTime   ;Read the current time
544                 CMP     R1,#0                   ;Are mouse buttons pressed?
545                 ADDEQ   R0,R0,#5                ;No -- then bump time on 5
546                 STR     R0,[R10,#12]            ;Store in the descriptor
547
548                 ; --- Slab the border in or out ---
549
550                 LDR     R0,[R10,#0]             ;Reload window handle
551                 LDRB    R2,s_slabcol            ;Get the slab colour nicely
552                 BL      swi_doslab              ;Do the slabbing operation
553                 LDMVSFD R13!,{R0-R2,R10,PC}     ;If it failed, return error
554
555                 SUB     R13,R13,#20             ;Space for a pointer block
556                 MOV     R1,R13                  ;Point to the block
557                 SWI     XWimp_GetPointerInfo    ;Read current mouse state
558                 LDR     R1,[R13,#8]             ;Load the button state
559                 ADD     R13,R13,#20             ;Restore the stack pointer
560                 CMP     R1,#0                   ;Are there buttons pressed?
561                 ORREQ   R2,R2,#256              ;Yes -- set a flag bit then
562                 STR     R2,[R10,#8]             ;Store the old icon colour
563
564                 ; --- Say to pause on unslabs in flags ---
565
566                 LDR     R14,s_flags             ;Get the flags word
567                 BIC     R14,R14,#s_UNSLAB       ;Clear unslab bit
568                 STR     R14,s_flags             ;Store flags word back
569
570                 ; --- Return to caller ---
571
572                 LDMFD   R13!,{R0-R2,R10,PC}^    ;Return to caller
573
574                 LTORG
575
576 ; --- Sculptrix_UnslabIcon ---
577 ;
578 ; On entry:     R2 == pointer to descriptor filled in by Sculptrix_SlabIcon
579 ; On exit:      --
580
581 swi_unslab      ROUT
582
583                 STMFD   R13!,{R0-R2,R10,R14}    ;Stack my registers
584
585                 ; --- Find out if we need to do any slabbing ---
586
587                 LDR     R14,[R2,#8]             ;Get the icon colour
588                 CMP     R14,#-1                 ;Is it nonslabbed?
589                 LDMEQFD R13!,{R0-R2,R10,PC}^
590
591                 ; --- Do we unslab quickly? ---
592
593                 MOV     R10,R2                  ;Look after slab block
594                 SUB     R13,R13,#36             ;To read the window state
595                 LDR     R0,s_flags              ;Get the flags word
596                 TST     R0,#s_UNSLAB            ;Is the unslab bit set?
597                 BNE     %03swi_unslab           ;Yes -- skip past the wait
598
599                 ; --- Wait the requisite quantity of time ---
600
601                 LDR     R0,[R10,#0]             ;Get the window handle
602                 MOV     R1,R13                  ;Point to the block
603                 STR     R0,[R1,#0]              ;Store in the block
604                 SWI     XWimp_GetWindowState    ;Get info about the window
605                 BVS     %01swi_unslab           ;It must have been deleted
606
607                 LDR     R0,[R1,#32]             ;Get the window flags
608                 TST     R0,#1<<16               ;Is the window open?
609                 BEQ     %01swi_unslab           ;And just wait the time out
610
611                 ; --- Wait for the mouse to be released ---
612
613                 LDR     R14,[R10,#8]            ;Load colour and flags bits
614                 TST     R14,#256                ;Is the `no mouse' bit set?
615                 BNE     %01swi_unslab           ;And do the wait operation
616
617 00swi_unslab    SWI     XOS_Mouse               ;Read mouse information
618                 CMP     R2,#0                   ;Are the buttons released?
619                 BNE     %00swi_unslab           ;No -- keep waiting
620                 B       %03swi_unslab           ;Do the actual unslab
621
622                 ; --- Wait for the timer to elapse ---
623
624 01swi_unslab    LDR     R1,[R10,#12]            ;Load the slab time
625                 ADD     R1,R1,#10               ;Work out unslab time
626 02swi_unslab    SWI     XOS_ReadMonotonicTime   ;Get the current time
627                 CMP     R1,R0                   ;How do they compare?
628                 BPL     %02swi_unslab           ;Too low -- go round again
629
630                 ; --- Actually unslab the icon ---
631
632 03swi_unslab    ADD     R13,R13,#36             ;Reclaim the stack space
633                 LDMIA   R10,{R0-R2}             ;Get window, icon and colour
634                 AND     R2,R2,#255              ;Clear flags bits etc.
635                 BL      swi_doslab              ;Unslab the icon
636
637                 ; --- Remember we've done this now ---
638
639                 LDR     R0,s_flags              ;Get the flags word again
640                 ORR     R0,R0,#s_UNSLAB         ;Set the unslab bit
641                 STR     R0,s_flags              ;Store the flags word away
642
643                 ; --- Return to caller ---
644
645                 LDMFD   R13!,{R0-R2,R10,PC}^    ;Return to caller
646
647                 LTORG
648
649 ; --- Sculptrix_BoundingBox ---
650 ;
651 ; On entry:     R1 == pointer to an icon block
652 ; On exit:      R0 == 0 if there was no border
653 ;               block updated to reflect border width
654
655 swi_bbox        ROUT
656
657                 STMFD   R13!,{R1-R6,R14}        ;Stash registers
658                 MOV     R3,#0                   ;Start from the beginning
659 00swi_bbox      MOV     R0,R1                   ;Point to block
660                 MOV     R2,#'X'                 ;The correct magic command
661                 BL      box_findValid           ;Find the validation string
662                 CMP     R2,#0                   ;Was it not there?
663                 MOVEQ   R0,#0                   ;Mark as nonpresent
664                 LDMEQFD R13!,{R1-R6,PC}^        ;Then return
665                 LDRB    R0,[R2,#1]              ;Get the border type
666                 CMP     R0,#'g'                 ;It could be a group box
667                 CMPNE   R0,#'G'                 ;Try both cases
668                 BEQ     %02swi_bbox             ;If so, be clever
669
670                 SUBS    R0,R0,#'0'              ;Turn into a number
671                 CMP     R0,#6                   ;Is it type 6?
672                 BEQ     %01swi_bbox             ;Yes -- be clever
673                 CMP     R0,#9                   ;Is it too big?
674                 MOVCS   R3,R2                   ;Not there if too high
675                 BCS     %00swi_bbox             ;So try for another one
676                 LDMIA   R1,{R3-R6}              ;Load the bounding box regs
677                 ADR     R2,box_borders          ;Get the border size table
678                 LDRB    R0,[R2,R0]              ;Load the border width
679                 SUB     R3,R3,R0
680                 SUB     R4,R4,R0
681                 ADD     R5,R5,R0
682                 ADD     R6,R6,R0
683                 STMIA   R1,{R3-R6}              ;Store the sizes back
684                 LDMFD   R13!,{R1-R6,PC}^        ;Return happy
685
686 01swi_bbox      LDMIA   R1,{R3-R6}              ;Load the bounding box regs
687                 SUB     R3,R3,#4
688                 ADD     R5,R5,#4
689                 STMIA   R1,{R3-R6}
690                 MOV     R0,#1
691                 LDMFD   R13!,{R1-R6,PC}^        ;Return happy
692
693 02swi_bbox      LDMIA   R1,{R3-R6}              ;Load the bounding box regs
694                 SUB     R3,R3,#8
695                 SUB     R4,R4,#8
696                 ADD     R5,R5,#8
697                 ADD     R6,R6,#32
698                 STMIA   R1,{R3-R6}
699                 MOV     R0,#1
700                 LDMFD   R13!,{R1-R6,PC}^        ;Return happy
701
702 box_borders     DCB     4,8,12,8,4,4,0,12,4
703
704                 ROUT
705
706 ; --- Sculptrix_PlotIcon ---
707 ;
708 ; On entry:     R0 == pointer to icon block
709 ;               R1 == pointer to redraw block
710
711 swi_ploticon    ROUT
712
713                 STMFD   R13!,{R0-R11,R14}       ;Stash loads of registers
714                 LDMIA   R0,{R0,R2-R8}           ;Load the icon coordinates
715                 STMFD   R13!,{R0,R2-R8}         ;Store them on the stack
716                 BL      box_readRectangle       ;Get the graphics window size
717                 MOV     R0,R13                  ;Point to the icon block
718                 BL      box_ploticon            ;Plot the icon
719                 ADD     R13,R13,#32             ;Reclaim the space
720                 LDMFD   R13!,{R0-R11,PC}^       ;Return to caller
721
722                 LTORG
723
724 ; --- Sculptrix_PlotGroup ---
725 ;
726 ; On entry:     R0 == pointer to icon block
727 ;               R1 == pointer to redraw block
728 ;               R2 == border type
729 ;               R3 == pointer to title string
730
731 swi_plotgroup   ROUT
732
733                 STMFD   R13!,{R0-R11,R14}       ;Stash loads of registers
734                 LDMIA   R0,{R0,R4-R10}          ;Load the icon coordinates
735                 STMFD   R13!,{R0,R4-R10}        ;Store them on the stack
736                 BL      box_readRectangle       ;Get the graphics window size
737                 MOV     R0,R13                  ;Point to the icon block
738                 MOV     R1,R2                   ;Get border type number
739                 MOV     R2,R3                   ;Get pointer to group string
740                 BL      box_dogroup             ;Plot the icon
741                 ADD     R13,R13,#32             ;Reclaim the space
742                 LDMFD   R13!,{R0-R11,PC}^       ;Return to caller
743
744                 LTORG
745
746 ; --- Sculptrix_SetSpriteArea ---
747 ;
748 ; On entry:     R0 == pointer to sprite area to use
749
750 swi_spritearea  ROUT
751
752                 STR     R0,s_sarea              ;Save it as sprite area ptr
753                 MOVS    PC,R14                  ;Return to caller
754
755 ; --- Sculptrix_UpdateIcon ---
756 ;
757 ; On entry:     R0 == window handle
758 ;               R1 == icon handle to update
759
760 swi_update      ROUT
761
762                 STMFD   R13!,{R0-R4,R14}        ;Save some registers
763                 SUB     R13,R13,#84             ;For icon and redraw blocks
764                 STMIA   R13,{R0,R1}             ;Save the bits at the bottom
765                 MOV     R1,R13                  ;Point to the icon block
766                 SWI     XWimp_GetIconState      ;Find the icon's bits out
767                 BVS     %99swi_update           ;If it failed, go ahead
768                 ADD     R2,R13,#40              ;Point to the redraw block
769                 LDR     R0,[R13,#0]             ;Get the window handle again
770                 STR     R0,[R2,#0]              ;Store window handle at base
771                 ADD     R0,R1,#8                ;Point to icon coordinates
772                 LDMIA   R0,{R0,R1,R3,R14}       ;Load the coordinates
773                 SUB     R0,R0,#16               ;Include the border nicely
774                 SUB     R1,R1,#16
775                 ADD     R3,R3,#16
776                 ADD     R14,R14,#16
777                 STMIB   R2,{R0,R1,R3,R14}       ;Save them out again
778                 MOV     R1,R2                   ;Point to this block
779                 SWI     XWimp_UpdateWindow      ;Start the window redraw
780                 BVS     %99swi_update           ;If it failed, go ahead
781
782 00swi_update    CMP     R0,#0                   ;Is this the end yet?
783                 BEQ     %80swi_update           ;Yes -- finish up nicely
784                 ADD     R0,R13,#8               ;Point to the icon block
785                 BL      swi_ploticon            ;Plot the icon on the screen
786                 SWI     XWimp_GetRectangle      ;Get the next redraw rect
787                 B       %00swi_update           ;And draw that one too
788
789 80swi_update    ADD     R13,R13,#84             ;Reclaim all that stack
790                 LDMFD   R13!,{R0-R4,PC}^        ;Return to caller
791
792 99swi_update    ADD     R13,R13,#88             ;Reclaim stack + R0
793                 LDMFD   R13!,{R1-R4,PC}         ;Return with V still set
794
795                 LTORG
796
797 ; --- Scultrix_SlabColour ---
798 ;
799 ; On entry:     --
800 ;
801 ; On exit:      R2 == standard slabbing-in colour
802
803 swi_slabcol     LDRB    R2,s_slabcol
804                 MOVS    PC,R14
805
806 ;----- Icon box redrawing ---------------------------------------------------
807
808 ; --- box_readRectangle ---
809 ;
810 ; On entry:     R1 == pointer to a Wimp redraw block
811 ; On exit:      R1 corrupted
812 ;               R5-R8 == adjusted, window-relative mouse rectangle
813 ;               R9,R10 == screen coords of window origin
814
815 box_readRectangle ROUT
816
817                 CMP     R1,#0                   ;Is there a redraw block?
818                 MOVEQ   R9,#0                   ;Yes -- don't translate box
819                 MOVEQ   R10,#0
820                 MOVEQS  PC,R14                  ;And return
821                 ADD     R1,R1,#16               ;Point to y1
822                 LDMIA   R1,{R8-R10}             ;Get coordinates from block
823                 SUB     R10,R8,R10              ;Get y origin position
824                 LDR     R8,[R1,#-12]            ;Get x0 value from block
825                 SUB     R9,R8,R9                ;Get x origin position
826
827                 ; --- Mangle the graphics rectangle ---
828
829                 ADD     R1,R1,#12               ;Point to the graphics window
830                 LDMIA   R1,{R5-R8}              ;Load the window posn
831                 SUB     R5,R5,R9                ;Convert to window coords
832                 SUB     R6,R6,R10
833                 SUB     R7,R7,R9
834                 SUB     R8,R8,R10
835
836                 SUB     R5,R5,#16               ;Add a little bit of leeway
837                 SUB     R6,R6,#32
838                 ADD     R7,R7,#16
839                 ADD     R8,R8,#16
840
841                 MOVS    PC,R14
842
843                 LTORG
844
845 ; --- box_ploticon ---
846 ;
847 ; On entry:     R0 == pointer to an icon block (writable)
848 ;               R5-R10 == as set by box_readRectangle
849 ; On exit:      R2-R4,R11 corrupted
850
851 box_ploticon    ROUT
852
853                 MOV     R3,#0
854 00box_ploticon  STMFD   R13!,{R14}
855                 MOV     R2,#'X'                 ;Find X commands in valid
856                 BL      box_findValid           ;Is it there?
857                 LDMFD   R13!,{R14}              ;Get return address back
858                 CMP     R2,#0                   ;Check
859                 MOVEQS  PC,R14                  ;No -- return to caller
860
861                 ; --- If the border has a capital letter, invert ---
862                 ;
863                 ; Also, choose the right colours for shaded boxes
864
865                 LDR     R11,[R0,#16]            ;Get the icon flags word
866                 EOR     R11,R11,#&005F0000      ;Toggle ESG and shaded bits
867                 TST     R11,#1<<22              ;Is the icon shaded?
868                 TSTNE   R11,#&001F0000          ;Or is ESG all set?
869                 ADRNE   R11,s_colours           ;No -- use normal colours
870                 ADREQ   R11,s_shadeCols         ;Yes -- use shaded colours
871
872                 LDRB    R4,[R2,#0]              ;Get the command letter
873                 TST     R4,#&20                 ;Is it upper case?
874                 ADDEQ   R11,R11,#1              ;Yes -- use offset colours
875
876                 ; --- Get the render type, and handle as required ---
877
878                 LDRB    R3,[R2,#1]              ;Get the border type number
879                 ORR     R4,R3,#&20              ;Convert to lower case
880
881                 CMP     R4,#'g'                 ;Is it a group box type?
882                 BEQ     box_plotgroup           ;Yes -- plot a group box
883
884                 CMP     R4,#'s'                 ;Is it a gadget text/sprite?
885                 BEQ     box_plottns             ;Yes -- plot cunningly
886
887                 ; --- Dispatch normal group border numbers ---
888
889                 SUB     R3,R3,#'0'              ;Convert to a digit
890                 CMP     R3,#(%02box_ploticon-%01box_ploticon)/4
891                 ADDCC   PC,PC,R3,LSL #2         ;Go to branch table
892                 B       %03box_ploticon         ;Not found -- try next valid
893
894 01box_ploticon  B       brd0                    ;Standard plinth
895                 B       brd1                    ;Group ridge/channel
896                 B       brd2                    ;Default action button
897                 B       brd3                    ;Writable wide border
898                 B       brd0                    ;Nonslabbing standard plinth
899                 B       brd5                    ;Plinth with ridge intersect
900                 B       brd6                    ;Channel terminators
901                 B       brd7                    ;Writable with black border
902                 B       brd8                    ;Like 4, only different
903 02box_ploticon
904
905 03box_ploticon  MOV     R3,R2                   ;Point to that command
906                 B       %00box_ploticon         ;And find the next string
907
908                 LTORG
909
910 ; --- box_setcolour ---
911 ;
912 ; On entry:     R0 == window handle
913 ;               R1 == icon handle
914 ;               R2 == colour to set
915 ; On exit:      R2 == old colour of icon
916
917 box_setcolour   ROUT
918
919                 STMFD   R13!,{R0,R1,R3-R5,R14}  ;Stack registers
920                 MOV     R5,R2                   ;Keep the colour safe
921                 SUB     R13,R13,#40             ;Make way for icon block
922                 STMIA   R13,{R0,R1}             ;Set up icon block
923                 MOV     R1,R13                  ;Point to block
924                 SWI     XWimp_GetIconState      ;Get info about icon
925                 ADDVS   R13,R13,#44             ;If it failed, reset stack
926                 LDMVSFD R13!,{R1,R3-R5,PC}      ;And return the error
927
928                 ; --- Check for fonts ---
929
930                 LDR     R0,[R1,#24]             ;Get icon flags word
931                 TST     R0,#1<<6                ;Check anti-aliased bit
932                 BEQ     %00box_setcolour        ;Reset -- do it normally
933                 ADD     R0,R1,#8                ;Point to icon definition
934                 MOV     R2,#'F'                 ;Find F validation string
935                 MOV     R3,#0                   ;Start from the beginning
936                 BL      box_findValid           ;Find it
937                 CMP     R2,#0                   ;Was it not there?
938                 ADDEQ   R13,R13,#40             ;No -- reset stack ptr
939                 LDMEQFD R13!,{R0,R1,R3-R5,PC}^  ;We did all we could
940                 ADR     R0,box_hexdigits        ;Point to hex digits table
941                 LDRB    R0,[R0,R5]              ;Get the right digit
942                 LDRB    R5,[R2,#1]              ;Get the old colour
943                 STRB    R0,[R2,#1]              ;Store in validation string
944                 SUB     R2,R5,#'0'              ;Turn into a digit
945                 CMP     R2,#10                  ;Is it a hex digit?
946                 SUBCS   R2,R2,#7                ;Yes -- get the number
947                 CMP     R2,#16                  ;Is it still too big?
948                 SUBCS   R2,R2,#&20              ;It must have been lower case
949
950                 ; --- Prod the icon into redrawing ---
951
952                 MOV     R0,#0                   ;Don't set either flags mask
953                 STR     R0,[R1,#8]              ;Set XOR mask
954                 STR     R0,[R1,#12]             ;Set BIC mask
955                 SWI     XWimp_SetIconState      ;Give the icon a little prod
956                 ADDVC   R13,R13,#40             ;It worked fine
957                 LDMVCFD R13!,{R0,R1,R3-R5,PC}^  ;So return happily
958                 ADD     R13,R13,#44             ;If it failed, reset stack
959                 LDMFD   R13!,{R1,R3-R5,PC}      ;And return the error
960
961                 ; --- Just set the colours in the time-honoured way ---
962
963 00box_setcolour MOV     R2,#&F                  ;Only want 4 bits
964                 AND     R2,R2,R0,LSR #28        ;Get old colour in R2
965                 MOV     R0,R5,LSL #28           ;Shift colour into position
966                 STR     R0,[R1,#8]              ;This is our XOR mask
967                 MOV     R0,#&F0000000           ;Only change the colour
968                 STR     R0,[R1,#12]             ;This is our BIC mask
969                 SWI     XWimp_SetIconState      ;Give the icon a little prod
970                 ADDVC   R13,R13,#40             ;It worked fine
971                 LDMVCFD R13!,{R0,R1,R3-R5,PC}^  ;So return happily
972                 ADD     R13,R13,#44             ;If it failed, reset stack
973                 LDMFD   R13!,{R1,R3-R5,PC}      ;And return the error
974
975 box_hexdigits   DCB     "0123456789ABCDEF",0
976
977                 LTORG
978
979 ;----- Messing with validation strings --------------------------------------
980
981 ; --- box_findValid ---
982 ;
983 ; On entry:     R0 == pointer to icon block
984 ;               R2 == character to find in block (not case-sensitive)
985 ;               R3 == old pointer to search from, or 0
986 ; On exit:      R3,R4 corrupted
987 ;               R2 points to command string if found, or 0
988
989 box_findValid   ROUT
990
991                 STMFD   R13!,{R3}               ;Preserve for later use
992
993                 ; --- Ensure the icon is text and indirected ---
994
995                 LDR     R3,[R0,#16]             ;Get flags word
996                 TST     R3,#1<<23               ;Is it deleted?
997                 MOVEQ   R4,#&100                ;Can't put 101 in one instr
998                 ORREQ   R4,R4,#&01              ;Check indirect and text
999                 ANDEQ   R3,R3,R4                ;Mask the bits off
1000                 CMPEQ   R3,R4                   ;Were they both set?
1001                 MOVNE   R2,#0                   ;Couldn't find it
1002                 ADDNE   R13,R13,#4
1003                 MOVNES  PC,R14                  ;No -- return huffily
1004
1005                 ; --- Find the validation string ---
1006
1007                 LDR     R3,[R0,#24]             ;Get pointer to valid string
1008                 CMP     R3,#-1                  ;Is it empty?
1009                 MOVEQ   R2,#0                   ;Yes -- not found
1010                 ADDEQ   R13,R13,#4
1011                 MOVEQS  PC,R14
1012
1013                 ; --- Start from the right index ---
1014
1015                 ORR     R2,R2,#&20              ;Make valid char lower case
1016                 LDMFD   R13!,{R4}               ;Get search index
1017                 STMFD   R13!,{R14}              ;Need another register
1018                 CMP     R4,#0                   ;Is it the start?
1019                 MOVNE   R3,R4                   ;No -- start from old pos
1020                 BNE     %02box_findValid        ;And skip this command
1021
1022                 ; --- Check the first char of a validation string ---
1023
1024 00box_findValid LDRB    R14,[R3],#1             ;Get a byte from string
1025                 ORR     R4,R14,#&20             ;Make lower case
1026                 CMP     R4,R2                   ;Is it a match?
1027                 SUBEQ   R2,R3,#1                ;Point back to character
1028                 LDMEQFD R13!,{PC}^              ;And return
1029                 MOV     R4,#0                   ;Not an excaped character
1030
1031                 ; --- Skip ahead to the next validation string ---
1032
1033 01box_findValid CMP     R14,#' '                ;Is it a control char?
1034                 MOVCC   R2,#0                   ;Yes -- not found
1035                 LDMCCFD R13!,{PC}^              ;And return
1036                 CMP     R4,#1                   ;Are we escaping?
1037                 MOVEQ   R4,#0                   ;Yes -- done that now
1038                 BEQ     %02box_findValid        ;So skip this bit
1039                 CMP     R14,#';'                ;Is it a semicolon?
1040                 BEQ     %00box_findValid        ;Yes -- try a new command
1041                 CMP     R14,#'\'                ;Is it a backslash?
1042                 MOVEQ   R4,#1                   ;Yes -- escape next char
1043 02box_findValid LDRB    R14,[R3],#1             ;Get another character
1044                 B       %01box_findValid        ;And try again
1045
1046                 LTORG
1047
1048 ;----- Plot text+sprite icons -----------------------------------------------
1049
1050 ; --- box_plottns ---
1051 ;
1052 ; On entry:     R0 == pointer to an icon block (writable)
1053 ;               R2 == pointer to the validation string command
1054 ;               R5-R10 == set up by box_readRectangle
1055
1056 box_plottns     ROUT
1057
1058                 STMFD   R13!,{R0-R4,R14}        ;Stack some registers
1059
1060                 ; --- Now copy the sprite name into the buffer ---
1061
1062                 LDR     R0,[R13,#0]             ;Find the icon pointer
1063                 MOV     R2,#'s'                 ;Find the sprite name
1064                 MOV     R3,#0                   ;Search from the beginning
1065                 BL      box_findValid           ;Find the string
1066                 CMP     R2,#0                   ;Did it find anything?
1067                 BEQ     %99box_plottns          ;No -- nothing to do then
1068
1069                 ; --- Copy the sprite name into the buffer ---
1070
1071                 ADR     R0,s_buffer             ;Point to my buffer
1072                 ADD     R2,R2,#1                ;Point to first sprite char
1073 00box_plottns   LDRB    R14,[R2],#1             ;Get the character
1074                 CMP     R14,#';'                ;Is it the string end?
1075                 CMPNE   R14,#','                ;Or the sprite name end?
1076                 CMPNE   R14,#&1F                ;Or the validation string end
1077                 MOVLS   R14,#0                  ;Yes -- null terminate
1078                 STRB    R14,[R0],#1             ;Store in the buffer
1079                 BHI     %00box_plottns          ;No -- loop round again
1080
1081                 ; --- Now read the sprite information ---
1082
1083                 STMFD   R13!,{R5,R6}            ;Save some registers
1084                 MOV     R0,#40                  ;Read sprite information
1085                 LDR     R1,s_sarea              ;Find the user's sprite area
1086                 ADR     R2,s_buffer             ;Point to the block
1087                 CMP     R1,#1                   ;Is it the wimp area
1088                 BEQ     %f05                    ;Yes -- skip on then
1089                 ORR     R0,R0,#&100             ;No -- say user sprite area
1090                 SWI     XOS_SpriteOp            ;So try to cope with that
1091                 BVC     %f06                    ;If OK skip onwards
1092
1093 05              MOV     R0,#40                  ;Read sprite information
1094                 ADR     R2,s_buffer             ;Point to the block
1095                 SWI     XWimp_SpriteOp
1096
1097 06              MOV     R0,R6                   ;Get the sprite's mode number
1098                 LDMFD   R13!,{R5,R6}            ;Unstack the registers
1099                 BVS     %99box_plottns          ;No sprite, no text
1100
1101                 ; --- Find the width of the sprite, then ---
1102
1103                 MOV     R1,#4                   ;Read XEigFactor
1104                 SWI     XOS_ReadModeVariable    ;Read the value then
1105                 BVS     %99box_plottns          ;No sprite mode, no text
1106                 MOV     R4,R3,LSL R2            ;Get sprite width in OS units
1107
1108                 ; --- Plot the icon to avoid strangeness ---
1109
1110                 LDR     R1,[R13,#0]             ;Get the icon block pointer
1111                 SWI     XWimp_PlotIcon          ;Plot the icon onto screen
1112
1113                 ; --- Copy the text string into the buffer ---
1114
1115                 LDR     R2,[R13,#8]             ;Find the validation string
1116                 ADD     R0,R2,#2                ;Point to the text string
1117                 ADR     R1,s_buffer             ;Point to the buffer start
1118
1119 10box_plottns   LDRB    R14,[R0],#1             ;Get a byte from the string
1120                 CMP     R14,#'\'                ;Is it an escape?
1121                 BEQ     %11box_plottns          ;Yes -- handle it specially
1122                 CMP     R14,#';'                ;Or the next command?
1123                 CMPNE   R14,#&1F                ;Is it a control character
1124                 MOVLS   R14,#0                  ;Yes -- store a null byte
1125                 STRB    R14,[R1],#1             ;Store the character away
1126                 BHI     %10box_plottns          ;No -- loop round again
1127                 B       %12box_plottns          ;Yes -- branch away
1128
1129 11box_plottns   LDRB    R14,[R0],#1             ;Get the escaped byte
1130                 CMP     R14,#32                 ;Is it a control character?
1131                 MOVCC   R14,#0                  ;Yes -- store a real term
1132                 STRB    R14,[R1],#1             ;Store the character away
1133                 BCS     %10box_plottns          ;And get another one
1134
1135                 ; --- Now plot the text part ---
1136
1137 12box_plottns   MOV     R0,#8                   ;Get the current font handle
1138                 SWI     XWimp_ReadSysInfo       ;Go and do that then
1139                 MOVVS   R0,#0                   ;If failed, assume system
1140                 CMP     R0,#0                   ;Is there a magic font?
1141                 LDR     R1,[R13,#0]             ;Find the icon block again
1142                 LDR     R0,[R1,#16]             ;Find the icon flags word
1143                 MOV     R14,#&FF000000          ;Mask for the old flags
1144                 ORRNE   R14,R14,#&00400000      ;If antialiased, copy shade
1145                 LDR     R2,=&00000111           ;Magic flags for text part
1146                 AND     R0,R0,R14               ;Keep original colours
1147                 ORR     R0,R0,R2                ;Mix 'n' match the icon flags
1148                 STR     R0,[R1,#16]             ;Store that back again
1149                 LDR     R0,[R1,#0]              ;Get left icon edge
1150                 ADD     R0,R0,R4                ;Offset by the right amount
1151                 STR     R0,[R1,#0]              ;Store it back again
1152                 ADR     R14,s_buffer            ;Find the buffer pointer
1153                 STR     R14,[R1,#20]            ;Point to the text string
1154                 MOV     R0,#-1                  ;No validation string pliz
1155                 STR     R0,[R1,#24]             ;Store it in the buffer
1156                 SWI     XWimp_PlotIcon          ;And stick it on the screen
1157
1158                 ; --- Tidy up and leave ---
1159
1160 99box_plottns   LDMFD   R13!,{R0-R4,PC}^        ;Return to caller if OK
1161
1162                 LTORG
1163
1164 ;----- Plot group boxes -----------------------------------------------------
1165
1166 ; --- box_plotgroup ---
1167 ;
1168 ; On entry:     R0 == pointer to an icon block (writable)
1169 ;               R2 == pointer to the validation string command
1170 ;               R5-R10 == set up by box_readRectangle
1171
1172 box_plotgroup   ROUT
1173
1174                 STMFD   R13!,{R0-R2,R14}        ;Stack some registers
1175
1176                 ; --- Copy the string into the buffer ---
1177
1178                 LDR     R2,[R13,#8]             ;Find the validation string
1179                 ADD     R0,R2,#3                ;Point to the text string
1180                 ADR     R1,s_buffer             ;Point to the buffer start
1181
1182 00box_plotgroup LDRB    R14,[R0],#1             ;Get a byte from the string
1183                 CMP     R14,#'\'                ;Is it an escape?
1184                 BEQ     %01box_plotgroup        ;Yes -- handle it specially
1185                 CMP     R14,#';'                ;Or the next command?
1186                 CMPNE   R14,#&1F                ;Is it a control character
1187                 MOVLS   R14,#0                  ;Yes -- terminate string
1188                 STRB    R14,[R1],#1             ;Store the character away
1189                 BHI     %00box_plotgroup        ;No -- loop round again
1190                 B       %02box_plotgroup        ;Yes -- branch away
1191
1192 01box_plotgroup LDRB    R14,[R0],#1             ;Get the escaped byte
1193                 CMP     R14,#32                 ;Is it a control character?
1194                 MOVCC   R14,#0                  ;Yes -- store a real term
1195                 STRB    R14,[R1],#1             ;Store the character away
1196                 BCS     %00box_plotgroup        ;And get another one
1197
1198                 ; --- Now plot the group border ---
1199
1200 02box_plotgroup LDR     R0,[R13,#0]             ;Get the icon block pointer
1201                 LDRB    R1,[R2,#2]              ;Get the border type
1202                 SUB     R1,R1,#'0'              ;Convert to an integer
1203                 ADR     R2,s_buffer             ;Point to the string
1204                 BL      box_dogroup             ;Handle the actual plotting
1205
1206                 ; --- Tidy up and leave ---
1207
1208 03box_plotgroup LDMFD   R13!,{R0-R2,PC}^        ;Return to caller if OK
1209
1210                 LTORG
1211
1212 ; --- box_dogroup ---
1213 ;
1214 ; On entry:     R0 == pointer to coordinates box
1215 ;               R1 == group border type number
1216 ;               R2 == pointer to group title string
1217
1218 box_dogroup     ROUT
1219
1220                 STMFD   R13!,{R11,R14}          ;Store registers
1221                 LDR     R14,s_flags             ;Get the flags word
1222                 TST     R14,#s_CHANNEL          ;Does the user want channels?
1223                 EORNE   R1,R1,#1                ;Yes -- toggle channelness
1224                 ADR     R14,%02box_dogroup
1225                 CMP     R1,#(%02box_dogroup-%01box_dogroup)/4
1226                 ADDCC   PC,PC,R1,LSL #2         ;Go to branch table
1227                 LDMFD   R13!,{R11,PC}^          ;Return to caller
1228
1229 01box_dogroup   B       grp0                    ;Standard ridge and plinth
1230                 B       grp1                    ;Acorn channel and gap
1231                 B       grp2                    ;Standard ridge and plinth
1232                 B       grp3                    ;Acorn channel and gap
1233
1234 02box_dogroup   LDMFD   R13!,{R11,PC}           ;Return to caller
1235
1236 ;----- Drawing group borders ------------------------------------------------
1237
1238 ; --- grp_titleicon ---
1239 ;
1240 ; On entry:     R0 == pointer to icon coordinates to bodge
1241 ;               R1 == left gap for icon title
1242 ;               R2 == pointer to title string
1243 ; On exit:      R0 == pointer to adjusted box
1244
1245 grp_titleicon   ROUT
1246
1247                 STMFD   R13!,{R0-R5,R14}        ;Stash registers away nicely
1248
1249                 ; --- Work out the length of the string ---
1250
1251                 MOV     R5,#0                   ;Nothing counted yet
1252 00grp_titleicon LDRB    R14,[R2,R5]             ;Get the next character
1253                 CMP     R14,#32                 ;Is it a control char?
1254                 ADD     R5,R5,#1                ;If not, bump the length
1255                 BCS     %00grp_titleicon        ;And loop round again
1256
1257                 MOV     R0,#8                   ;Read the Wimp font handle
1258                 SWI     XWimp_ReadSysInfo       ;Try and find it
1259                 MOVVS   R5,R5,LSL #4            ;Multiply by 16
1260                 BVS     %01grp_titleicon        ;If not supported, ignore
1261                 CMP     R0,#0                   ;Is there a font used?
1262                 MOVEQ   R5,R5,LSL #4            ;Multiply by 16
1263                 BEQ     %01grp_titleicon        ;If not, skip ahead a bit
1264
1265                 ; --- Work out the width of the string ---
1266
1267                 MOV     R1,#1000                ;Just something big
1268                 MOV     R2,#1000                ;Something else big :-)
1269                 SWI     XFont_Converttopoints   ;Convert them to millipts
1270                 SWI     XFont_SetFont           ;Set this as the current font
1271                 MOV     R3,R2                   ;Move these coords now
1272                 MOV     R2,R1
1273                 LDR     R1,[R13,#8]             ;Find the string pointer
1274                 MOV     R4,#-1                  ;Don't split the string
1275                 SWI     XFont_StringWidth       ;Find the width of the string
1276                 MOV     R1,R2                   ;Move the coords back again
1277                 MOV     R2,R3
1278                 SWI     XFont_ConverttoOS       ;Convert back to OS units
1279                 ADD     R5,R1,#16               ;Get the string width
1280
1281                 ; --- Now bodge the icon block ---
1282
1283 01grp_titleicon LDMIA   R13,{R0,R1}             ;Get block ptr and offset
1284                 LDMIA   R0,{R2,R3,R4,R14}       ;Get the icon coords
1285                 ADD     R2,R2,R1                ;Offset the left side
1286                 SUB     R3,R14,#20              ;Find bottom of group box
1287                 ADD     R4,R2,R5                ;Add on the string width
1288                 ADD     R14,R14,#28             ;Find the top of the icon
1289                 STMIA   R0,{R2,R3,R4,R14}       ;Store the modified coords
1290
1291                 ; --- Bodge the rest of the icon ---
1292
1293                 LDR     R2,[R13,#8]             ;Find the string pointer
1294                 STR     R2,[R0,#20]             ;Store this as data
1295                 MOV     R2,#-1                  ;No validation string
1296                 STR     R2,[R0,#24]             ;Store this away too
1297                 MOV     R2,#1                   ;It doesn't care about this
1298                 STR     R2,[R0,#28]             ;Store this as the length
1299                 LDR     R2,=&17000139           ;Icon flags word
1300                 STR     R2,[R0,#16]             ;Store this as icon flags
1301
1302                 LDMFD   R13!,{R0-R5,PC}^        ;Return to caller
1303
1304 ; --- grp_fillBorder ---
1305 ;
1306 ; On entry:     R5-R8 == box coordinates (!)
1307 ;               R9,R10 == window origin coordinates on the screen
1308 ;
1309 ; Removed in version 1.14
1310
1311  [ {FALSE}
1312
1313 grp_fillBorder  ROUT
1314
1315                 STMFD   R13!,{R0-R4,R14}        ;Save some registers
1316                 MOV     R0,#1                   ;Grey background
1317                 SWI     XWimp_SetColour         ;Set up the background
1318                 MOV     R0,#4                   ;Move absolute
1319                 ADD     R1,R5,R9                ;Translate left hand side
1320                 ADD     R2,R6,R10               ;Translate bottom edge
1321                 SWI     XOS_Plot                ;Move there
1322                 MOV     R0,#101                 ;Filled rectangle, absolute
1323                 ADD     R1,R7,R9                ;Translate right hand side
1324                 ADD     R2,R8,R10               ;Translate top edge
1325                 LDMIA   R12,{R3,R4}             ;Get the pixel sizes
1326                 SUB     R1,R1,R3                ;Chop a bit off the right
1327                 SUB     R2,R2,R4                ;Chop a bit off the top
1328                 SWI     XOS_Plot                ;Fill in the background
1329                 LDMFD   R13!,{R0-R4,PC}^        ;Restore the registers
1330
1331                 LTORG
1332  ]
1333
1334 ; --- grp 0 ---
1335
1336 grp0            STMFD   R13!,{R1-R8,R14}        ;Stash registers
1337
1338                 LDMIA   R0,{R5-R8}              ;Get the border coordinates
1339                 STMFD   R13!,{R5-R8}            ;Save them on the stack
1340                 MOV     R3,R0                   ;Keep this pointer safe
1341 ;               BL      grp_fillBorder          ;Don't fill in 1.14
1342
1343                 ; --- Translate the icon block ---
1344
1345                 MOV     R1,#16                  ;Small offset here
1346                 BL      grp_titleicon           ;Find the icon position
1347
1348                 ; --- Now display the main border ---
1349
1350                 LDMIA   R0,{R5-R8}              ;Save this position
1351                 MOV     R0,R13                  ;Point to border position
1352                 MOV     R1,R3                   ;Point to title position
1353                 ADR     R11,s_colours           ;Point to colour table
1354                 BL      gborder                 ;Plot the group border
1355
1356                 ; --- Now display the main title border ---
1357
1358                 STMIA   R3,{R5-R8}              ;Restore saved position
1359                 MOV     R0,R3                   ;Point to the position
1360                 BL      brd5                    ;Plot the top plinth
1361                 STMIA   R0,{R5-R8}              ;Restore that again
1362                 MOV     R1,R0                   ;Point to the icon block
1363                 SWI     XWimp_PlotIcon          ;Now plot the icon on top
1364                 ADD     R13,R13,#16             ;Restore stack pointer
1365                 LDMFD   R13!,{R1-R8,PC}         ;Return to caller
1366
1367 ; --- grp 1 ---
1368
1369 grp1            STMFD   R13!,{R1-R8,R14}        ;Stash registers
1370
1371                 LDMIA   R0,{R5-R8}              ;Get the border coordinates
1372                 STMFD   R13!,{R5-R8}            ;Save them on the stack
1373                 MOV     R3,R0                   ;Keep this pointer safe
1374
1375                 ; --- Translate the icon block ---
1376
1377                 MOV     R1,#16                  ;Small offset here
1378                 BL      grp_titleicon           ;Find the icon position
1379
1380                 ; --- Now display the main border ---
1381
1382                 LDMIA   R0,{R5-R8}              ;Save this position
1383                 MOV     R0,R13                  ;Point to border position
1384                 MOV     R1,R3                   ;Point to title position
1385                 LDR     R11,s_flags             ;Get the flags word
1386                 TST     R11,#s_FAINTCHAN        ;Is it meant to be faint
1387                 ADREQ   R11,s_colours+1         ;Point to colour table
1388                 ADRNE   R11,s_shadeCols+1
1389                 BL      gborder                 ;Plot the group border
1390
1391                 ; --- Now display the main title border ---
1392
1393                 STMIA   R3,{R5-R8}              ;Restore saved position
1394                 MOV     R0,R3                   ;Point to the position
1395                 BL      brd6                    ;Plot the top thingy
1396                 STMIA   R0,{R5-R8}              ;Restore that again
1397                 MOV     R1,R0                   ;Point to the icon block
1398
1399                 ; --- Stop the top bit from being filled ---
1400
1401                 LDR     R0,[R1,#16]
1402                 BIC     R0,R0,#(1<<5)           ;Clear filled flag
1403                 STR     R0,[R1,#16]
1404
1405                 SWI     XWimp_PlotIcon          ;Now plot the icon on top
1406                 ADD     R13,R13,#16             ;Restore stack pointer
1407                 LDMFD   R13!,{R1-R8,PC}         ;Return to caller
1408
1409 ; --- grp 2 ---
1410
1411 grp2            STMFD   R13!,{R1-R8,R14}        ;Stash registers
1412
1413                 LDMIA   R0,{R5-R8}              ;Get the border coordinates
1414                 STMFD   R13!,{R5-R8}            ;Save them on the stack
1415                 MOV     R3,R0                   ;Keep this pointer safe
1416 ;               BL      grp_fillBorder          ;Don't fill in 1.14
1417
1418                 ; --- Translate the icon block ---
1419
1420                 MOV     R1,#32                  ;Large offset here
1421                 BL      grp_titleicon           ;Find the icon position
1422
1423                 ; --- Now display the main border ---
1424
1425                 LDMIA   R0,{R5-R8}              ;Save this position
1426                 MOV     R0,R13                  ;Point to border position
1427                 MOV     R1,R3                   ;Point to title position
1428                 ADR     R11,s_colours           ;Point to colour table
1429                 BL      gborder                 ;Plot the group border
1430
1431                 ; --- Now display the main title border ---
1432
1433                 STMIA   R3,{R5-R8}              ;Restore saved position
1434                 MOV     R0,R3                   ;Point to the position
1435                 BL      brd5                    ;Plot the top plinth
1436                 STMIA   R0,{R5-R8}              ;Restore that again
1437                 MOV     R1,R0                   ;Point to the icon block
1438                 SWI     XWimp_PlotIcon          ;Now plot the icon on top
1439                 ADD     R13,R13,#16             ;Restore stack pointer
1440                 LDMFD   R13!,{R1-R8,PC}         ;Return to caller
1441
1442 ; --- grp 3 ---
1443
1444 grp3            STMFD   R13!,{R1-R8,R14}        ;Stash registers
1445
1446                 LDMIA   R0,{R5-R8}              ;Get the border coordinates
1447                 STMFD   R13!,{R5-R8}            ;Save them on the stack
1448                 MOV     R3,R0                   ;Keep this pointer safe
1449
1450                 ; --- Translate the icon block ---
1451
1452                 MOV     R1,#32                  ;Small offset here
1453                 BL      grp_titleicon           ;Find the icon position
1454
1455                 ; --- Now display the main border ---
1456
1457                 LDMIA   R0,{R5-R8}              ;Save this position
1458                 MOV     R0,R13                  ;Point to border position
1459                 MOV     R1,R3                   ;Point to title position
1460                 LDR     R11,s_flags             ;Get the flags word
1461                 TST     R11,#s_FAINTCHAN        ;Is it meant to be faint
1462                 ADREQ   R11,s_colours+1         ;Point to colour table
1463                 ADRNE   R11,s_shadeCols+1
1464                 BL      gborder                 ;Plot the group border
1465
1466                 ; --- Now display the main title border ---
1467
1468                 STMIA   R3,{R5-R8}              ;Restore saved position
1469                 MOV     R0,R3                   ;Point to the position
1470                 BL      brd6                    ;Plot the top thingy
1471                 STMIA   R0,{R5-R8}              ;Restore that again
1472                 MOV     R1,R0                   ;Point to the icon block
1473
1474                 ; --- Stop the top bit from being filled ---
1475
1476                 LDR     R0,[R1,#16]
1477                 BIC     R0,R0,#(1<<5)           ;Clear filled flag
1478                 STR     R0,[R1,#16]
1479
1480                 SWI     XWimp_PlotIcon          ;Now plot the icon on top
1481                 ADD     R13,R13,#16             ;Restore stack pointer
1482                 LDMFD   R13!,{R1-R8,PC}         ;Return to caller
1483
1484 ; --- gborder ---
1485 ;
1486 ; On entry:     R0 == pointer to icon coordinates block (writable)
1487 ;               R1 == pointer to title icon coordinate
1488 ;               R9 == x coord of window origin on screen
1489 ;               R10 == y coord of window origin on screen
1490 ;
1491 ; Plots a group border such that it doesn't overlap the title icon at all.
1492
1493 gborder         ROUT
1494
1495                 STMFD   R13!,{R0-R5,R8,R14}     ;Stack registers away
1496                 MOV     R8,R1                   ;Keep this pointer safe
1497
1498                 ; --- Now convert all the boxes to screen coords ---
1499
1500                 LDMIA   R0,{R1-R4}              ;Get the straight box
1501                 BL      box_convert
1502                 STMIA   R0,{R1-R4}              ;Write it back nicely
1503
1504                 SUB     R1,R1,#4                ;Now expand it a little
1505                 SUB     R2,R2,#4
1506                 ADD     R3,R3,#4
1507                 ADD     R4,R4,#4
1508                 STMFD   R13!,{R1-R4}            ;Stash them on the stack
1509
1510                 LDMIA   R8,{R1-R4}              ;Get the title position
1511                 BL      box_convert
1512
1513                 STMFD   R13!,{R1-R4}            ;Save them on the stack too
1514
1515                 ; --- Now render all the parts except for the top ---
1516
1517                 MOV     R1,R0
1518                 LDRB    R0,[R11,#0]
1519                 SWI     XWimp_SetColour
1520                 ADD     R0,R13,#16
1521                 BL      prim_left
1522                 MOV     R0,R1
1523                 BL      prim_right
1524                 LDRB    R0,[R11,#1]
1525                 SWI     XWimp_SetColour
1526                 ADD     R0,R13,#16
1527                 BL      prim_right
1528                 BL      prim_bottom
1529                 MOV     R0,R1
1530                 BL      prim_left
1531                 LDRB    R0,[R11,#0]
1532                 SWI     XWimp_SetColour
1533                 MOV     R0,R1
1534                 BL      prim_bottom
1535
1536                 ; --- Now fix up the top coordinates ---
1537
1538                 LDR     R0,[R13,#8]             ;Get right side of title box
1539                 ADD     R0,R0,#8                ;Move it clear of the group
1540                 LDR     R5,[R1,#0]              ;Get the old left hand side
1541                 STR     R0,[R1,#0]              ;Store as left side here
1542                 STR     R0,[R13,#16]            ;And left side for other one
1543
1544                 ; --- Now render the left top sides ---
1545
1546                 ADD     R0,R13,#16
1547                 BL      prim_top
1548                 LDRB    R0,[R11,#1]
1549                 SWI     XWimp_SetColour
1550                 MOV     R0,R1
1551                 BL      prim_top
1552
1553                 ; --- Now get the right top sides ---
1554
1555                 STR     R5,[R1,#0]              ;Store it back again
1556                 SUB     R5,R5,#4                ;Fiddle for outer border
1557                 STR     R5,[R13,#16]            ;Save in outer border block
1558
1559                 LDR     R0,[R13,#0]             ;Get right hand side of this
1560                 SUB     R0,R0,#4                ;Move it over a little
1561                 STR     R0,[R1,#8]              ;Store as rightside here
1562                 STR     R0,[R13,#24]            ;And right side for other one
1563
1564                 ; --- Now render the right top sides ---
1565
1566                 MOV     R0,R1
1567                 BL      prim_top
1568                 LDRB    R0,[R11,#0]
1569                 SWI     XWimp_SetColour
1570                 ADD     R0,R13,#16
1571                 BL      prim_top
1572
1573                 ; --- Return -- it's all over ---
1574
1575                 ADD     R13,R13,#32             ;Restore the stack pointer
1576
1577                 LDMFD   R13!,{R0-R5,R8,PC}^     ;Return to caller
1578
1579                 LTORG
1580
1581 ;----- Draw the border types ------------------------------------------------
1582 ;
1583 ; All entry:    R0 == pointer to icon coordinates block (writable)
1584 ;               R9 == x coord of window origin on screen
1585 ;               R10 == y coord of window origin on screen
1586
1587 ; --- brd8 ---
1588
1589 brd8            ROUT
1590
1591                 STMFD   R13!,{R14}
1592                 LDR     R14,s_flags
1593                 TST     R14,#s_FAINTCHAN
1594                 ANDNE   R14,R11,#3
1595                 ADRNE   R11,s_shadeCols
1596                 ADDNE   R11,R11,R14
1597                 LDMFD   R13!,{R14}
1598
1599 ; --- brd0 ---
1600
1601 brd0            ROUT
1602
1603                 STMFD   R13!,{R0-R4,R14}        ;Stack registers away
1604                 LDMIA   R0,{R1-R4}              ;Load the coordinates
1605                 BL      box_convert
1606                 STMIA   R0,{R1-R4}
1607                 MOV     R1,R0                   ;Keep pointer to box
1608
1609                 ; --- Draw bits of the border ---
1610
1611                 LDRB    R0,[R11,#0]
1612                 SWI     XWimp_SetColour
1613                 MOV     R0,R1
1614                 BL      prim_left
1615                 LDRB    R0,[R11,#1]
1616                 SWI     XWimp_SetColour
1617                 MOV     R0,R1
1618                 BL      prim_right
1619                 BL      prim_bottom
1620                 LDRB    R0,[R11,#0]
1621                 SWI     XWimp_SetColour
1622                 MOV     R0,R1
1623                 BL      prim_top
1624
1625                 LDMFD   R13!,{R0-R4,PC}^        ;Return to caller
1626
1627                 LTORG
1628
1629 ; --- brd1 ---
1630
1631 brd1            ROUT
1632
1633                 STMFD   R13!,{R0-R4,R14}        ;Stack registers away
1634                 SUB     R13,R13,#16             ;Make space for another blk
1635                 LDMIA   R0,{R1-R4}              ;Load the coordinates
1636                 BL      box_convert
1637                 STMIA   R0,{R1-R4}
1638                 SUB     R1,R1,#4
1639                 SUB     R2,R2,#4
1640                 ADD     R3,R3,#4
1641                 ADD     R4,R4,#4
1642                 STMIA   R13,{R1-R4}
1643                 MOV     R1,R0                   ;Keep pointer to box
1644
1645                 ; --- Draw bits of the border ---
1646
1647                 LDRB    R0,[R11,#0]
1648                 SWI     XWimp_SetColour
1649                 MOV     R0,R13
1650                 BL      prim_left
1651                 MOV     R0,R1
1652                 BL      prim_right
1653                 LDRB    R0,[R11,#1]
1654                 SWI     XWimp_SetColour
1655                 MOV     R0,R13
1656                 BL      prim_right
1657                 BL      prim_bottom
1658                 MOV     R0,R1
1659                 BL      prim_left
1660                 BL      prim_top
1661                 LDRB    R0,[R11,#0]
1662                 SWI     XWimp_SetColour
1663                 MOV     R0,R13
1664                 BL      prim_top
1665                 MOV     R0,R1
1666                 BL      prim_bottom
1667
1668                 ADD     R13,R13,#16
1669                 LDMFD   R13!,{R0-R4,PC}^        ;Return to caller
1670
1671                 LTORG
1672
1673 ; --- brd2 ---
1674
1675 brd2            ROUT
1676
1677                 STMFD   R13!,{R0-R4,R14}        ;Stack registers away
1678                 LDMIA   R0,{R1-R4}              ;Load the coordinates
1679                 BL      box_convert
1680                 STMIA   R0,{R1-R4}
1681                 SUB     R1,R1,#4
1682                 SUB     R2,R2,#4
1683                 ADD     R3,R3,#4
1684                 ADD     R4,R4,#4
1685                 STMFD   R13!,{R1-R4}
1686                 SUB     R1,R1,#4
1687                 SUB     R2,R2,#4
1688                 ADD     R3,R3,#4
1689                 ADD     R4,R4,#4
1690                 STMFD   R13!,{R1-R4}
1691                 MOV     R1,R0                   ;Keep pointer to box
1692
1693                 ; --- Draw inside border ---
1694
1695                 LDRB    R0,[R11,#0]
1696                 SWI     XWimp_SetColour
1697                 MOV     R0,R1
1698                 BL      prim_left
1699                 LDRB    R0,[R11,#1]
1700                 SWI     XWimp_SetColour
1701                 MOV     R0,R1
1702                 BL      prim_right
1703                 BL      prim_bottom
1704                 LDRB    R0,[R11,#0]
1705                 SWI     XWimp_SetColour
1706                 MOV     R0,R1
1707                 BL      prim_top
1708
1709                 ; --- Draw rim around the middle ---
1710                 ;
1711                 ; It's overkill, but I'll use the calls below for this
1712
1713                 LDR     R0,s_rimcol
1714                 SWI     XWimp_SetColour
1715                 ADD     R0,R13,#16
1716                 BL      prim_left
1717                 BL      prim_right
1718                 BL      prim_top
1719                 BL      prim_bottom
1720
1721                 ; --- Draw surrounding border ---
1722
1723                 BIC     R11,R11,#1              ;Round pointer downwards
1724                 LDR     R0,[R11,#1]
1725                 SWI     XWimp_SetColour
1726                 MOV     R0,R13
1727                 BL      prim_left
1728                 LDR     R0,[R11,#0]
1729                 SWI     XWimp_SetColour
1730                 MOV     R0,R13
1731                 BL      prim_right
1732                 BL      prim_bottom
1733                 LDR     R0,[R11,#1]
1734                 SWI     XWimp_SetColour
1735                 MOV     R0,R13
1736                 BL      prim_top
1737
1738                 ADD     R13,R13,#32
1739                 LDMFD   R13!,{R0-R4,PC}^        ;Return to caller
1740
1741                 LTORG
1742 ; --- brd3 ---
1743
1744 brd3            ROUT
1745
1746                 STMFD   R13!,{R0-R4,R14}        ;Stack registers away
1747                 LDMIA   R0,{R1-R4}              ;Load the coordinates
1748                 BL      box_convert
1749                 STMIA   R0,{R1-R4}
1750                 MOV     R1,R0                   ;Save this away
1751
1752                 ; --- Fill in the inside section to overwrite marbling ---
1753
1754                 MOV     R0,#1
1755                 SWI     XWimp_SetColour
1756                 MOV     R0,R1
1757                 BL      prim_left
1758                 BL      prim_right
1759                 BL      prim_bottom
1760                 BL      prim_top
1761
1762                 LDMIA   R0,{R1-R4}
1763                 SUB     R1,R1,#4
1764                 SUB     R2,R2,#4
1765                 ADD     R3,R3,#4
1766                 ADD     R4,R4,#4
1767                 STMIA   R0,{R1-R4}
1768                 MOV     R1,R0                   ;Keep pointer to box
1769
1770                 ; --- Draw bits of the border ---
1771
1772                 LDRB    R0,[R11,#1]
1773                 SWI     XWimp_SetColour
1774                 MOV     R0,R1
1775                 BL      prim_left
1776                 LDRB    R0,[R11,#0]
1777                 SWI     XWimp_SetColour
1778                 MOV     R0,R1
1779                 BL      prim_right
1780                 BL      prim_bottom
1781                 LDRB    R0,[R11,#1]
1782                 SWI     XWimp_SetColour
1783                 MOV     R0,R1
1784                 BL      prim_top
1785
1786                 LDMFD   R13!,{R0-R4,PC}^        ;Return to caller
1787
1788                 LTORG
1789
1790 ; --- brd5 ---
1791
1792 brd5            ROUT
1793
1794                 STMFD   R13!,{R0-R4,R14}        ;Stack registers away
1795                 LDMIA   R0,{R1-R4}              ;Load the coordinates
1796                 BL      box_convert
1797                 STMIA   R0,{R1-R4}
1798                 SUB     R14,R4,R2               ;Get height of box
1799                 ADD     R2,R2,R14,LSR #1        ;Centre R2 in box
1800                 SUB     R4,R2,#4                ;Move thing to right place
1801                 ADD     R2,R2,#4                ;And copy across
1802                 SUB     R3,R1,#4                ;Set up the nick width
1803                 STMFD   R13!,{R1-R4}            ;Stash them on the stack
1804                 MOV     R1,R0                   ;Keep pointer to box
1805
1806                 ; --- Draw bits of the border ---
1807
1808                 LDRB    R0,[R11,#0]
1809                 SWI     XWimp_SetColour
1810                 MOV     R0,R1
1811                 BL      prim_left
1812                 LDRB    R0,[R11,#1]
1813                 SWI     XWimp_SetColour
1814                 MOV     R0,R1
1815                 BL      prim_right
1816                 BL      prim_bottom
1817                 MOV     R0,R13
1818                 BL      prim_top
1819                 LDRB    R0,[R11,#0]
1820                 SWI     XWimp_SetColour
1821                 MOV     R0,R1
1822                 BL      prim_top
1823                 LDMIA   R1,{R1-R3}
1824                 LDR     R2,[R13,#4]
1825                 ADD     R1,R3,#4
1826                 STMIA   R13,{R1-R3}
1827                 MOV     R0,R13
1828                 BL      prim_bottom
1829
1830                 ADD     R13,R13,#16
1831                 LDMFD   R13!,{R0-R4,PC}^        ;Return to caller
1832
1833                 LTORG
1834
1835 ; --- brd6 ---
1836
1837 brd6            ROUT
1838
1839                 STMFD   R13!,{R0-R4,R14}        ;Stack registers away
1840                 LDMIA   R0,{R1-R4}              ;Load the coordinates
1841                 BL      box_convert
1842                 STMIA   R0,{R1-R4}
1843                 SUB     R14,R4,R2               ;Get height of box
1844                 ADD     R2,R2,R14,LSR #1        ;Centre R2 in box
1845                 MOV     R4,R2                   ;Move thing to right place
1846                 SUB     R3,R1,#4                ;Set up the nick width
1847                 STMFD   R13!,{R1-R4}            ;Stash them on the stack
1848                 MOV     R1,R0                   ;Keep pointer to box
1849
1850                 ; --- Draw bits of the border ---
1851
1852                 LDRB    R0,[R11,#1]
1853                 SWI     XWimp_SetColour
1854                 MOV     R0,R13
1855                 BL      prim_left
1856                 LDRB    R0,[R11,#0]
1857                 SWI     XWimp_SetColour
1858                 MOV     R0,R13
1859                 BL      prim_top
1860
1861                 LDMIA   R1,{R1-R3}
1862                 LDR     R2,[R13,#4]
1863                 ADD     R1,R3,#4
1864                 STMIA   R13,{R1-R3}
1865
1866                 BL      prim_right
1867                 LDRB    R0,[R11,#1]
1868                 SWI     XWimp_SetColour
1869                 MOV     R0,R13
1870                 BL      prim_bottom
1871
1872                 ADD     R13,R13,#16
1873                 LDMFD   R13!,{R0-R4,PC}^        ;Return to caller
1874
1875                 LTORG
1876
1877 ; --- brd7 ---
1878
1879 brd7            ROUT
1880
1881                 STMFD   R13!,{R0-R10,R14}       ;Stack registers away
1882                 LDMIA   R0,{R1-R4}              ;Load the coordinates
1883                 BL      box_convert
1884                 STMFD   R13!,{R1-R4}
1885                 MOV     R10,R0                  ;Save this away
1886                 LDR     R9,[R10,#16]            ;Load the icon's flags
1887
1888                 ; --- Find out about the icon's colours ---
1889
1890                 TST     R9,#1<<6                ;Is it anti-aliased?
1891                 BEQ     %10brd7                 ;No -- skip this bit out then
1892
1893                 BIC     R9,R9,#&ff000000        ;Clear out the font handle
1894                 MOV     R2,#'F'                 ;Find font validation strings
1895                 MOV     R3,#0                   ;Start from the beginning
1896                 BL      box_findValid           ;Find the colour command
1897                 CMP     R2,#0                   ;Was it not there at all?
1898                 ORREQ   R9,R9,#&07000000        ;No -- use default colours
1899                 BEQ     %10brd7                 ;And skip to the end
1900
1901                 LDRB    R0,[R2,#1]              ;Load a byte from the string
1902                 SUB     R0,R0,#'0'              ;Turn it into a number
1903                 CMP     R0,#10                  ;Is it a letter, not a digit?
1904                 SUBCS   R0,R0,#7                ;Yes -- compensate for that
1905                 CMP     R0,#16                  ;Is it lowercase?
1906                 SUBCS   R0,R0,#&20              ;Yes -- deal with that case
1907
1908                 LDRB    R1,[R2,#2]              ;Load the next byte too
1909                 SUB     R1,R1,#'0'              ;Turn it into a number
1910                 CMP     R1,#10                  ;Is it a letter, not a digit?
1911                 SUBCS   R1,R1,#7                ;Yes -- compensate for that
1912                 CMP     R1,#16                  ;Is it lowercase?
1913                 SUBCS   R1,R1,#&20              ;Yes -- deal with that case
1914
1915                 ORR     R9,R9,R0,LSL #28        ;Fit the background colour in
1916                 ORR     R9,R9,R1,LSL #24        ;And the foreground colour
1917
1918                 ; --- First plot the whole background ---
1919
1920 10brd7          ADR     R14,s_dx                ;Point to the pixel sizes
1921                 LDMIA   R14,{R7,R8}             ;Load them out nicely
1922                 LDMFD   R13!,{R3-R6}            ;Load the coordinates out
1923
1924                 TST     R9,#1<<5                ;Is the icon filled?
1925                 BEQ     %20brd7                 ;No -- skip this bit out
1926
1927                 MOV     R0,R9,LSR #28           ;Get the background colour
1928                 AND     R0,R0,#&f               ;Clear all the other bits
1929                 SWI     XWimp_SetColour         ;Set the bit's colour
1930
1931                 MOV     R0,#plot_MOVE+plot_ABSOLUTE
1932                 SUB     R1,R3,#4
1933                 SUB     R2,R4,#4
1934                 ADD     R1,R1,R7                ;Don't overlap the border
1935                 ADD     R2,R2,R8
1936                 SWI     XOS_Plot                ;Move to the bottom left
1937
1938                 MOV     R0,#plot_RECTFILL+plot_ABSOLUTE+plot_FORE
1939                 ADD     R1,R5,#4
1940                 ADD     R2,R6,#4
1941                 SUB     R1,R1,R7,LSL #1
1942                 SUB     R2,R2,R8,LSL #1
1943                 SWI     XOS_Plot                ;Fill in the background
1944
1945                 ; --- Plot the foreground border now ---
1946
1947 20brd7          MOV     R0,R9,LSR #24           ;Get the foreground colour
1948                 AND     R0,R0,#&f               ;Clear all the other bits
1949                 SWI     XWimp_SetColour         ;Set the bit's colour
1950
1951                 MOV     R0,#plot_MOVE+plot_ABSOLUTE
1952                 SUB     R1,R3,#4
1953                 SUB     R2,R4,#4
1954                 SWI     XOS_Plot                ;Move to the bottom left
1955
1956                 MOV     R0,#plot_LINE+plot_ABSOLUTE+plot_FORE
1957                 ADD     R1,R5,#4
1958                 SUB     R1,R1,R7
1959                 SUB     R2,R4,#4
1960                 SWI     XOS_Plot                ;Plot the left hand side
1961
1962                 MOV     R0,#plot_LINE+plot_ABSOLUTE+plot_FORE
1963                 ADD     R1,R5,#4
1964                 SUB     R1,R1,R7
1965                 ADD     R2,R6,#4
1966                 SUB     R2,R2,R8
1967                 SWI     XOS_Plot                ;Plot the top edge
1968
1969                 MOV     R0,#plot_LINE+plot_ABSOLUTE+plot_FORE
1970                 SUB     R1,R3,#4
1971                 ADD     R2,R6,#4
1972                 SUB     R2,R2,R8
1973                 SWI     XOS_Plot                ;Plot the right hand side
1974
1975                 MOV     R0,#plot_LINE+plot_ABSOLUTE+plot_FORE
1976                 SUB     R1,R3,#4
1977                 SUB     R2,R4,#4
1978                 SWI     XOS_Plot                ;Plot the bottom edge
1979
1980                 ; --- Now plot a writable border (type 3) ---
1981
1982                 LDMIA   R10,{R0-R3}             ;Load the coordinates
1983                 SUB     R0,R0,#4                ;Modify for the extra border
1984                 SUB     R1,R1,#4
1985                 ADD     R2,R2,#4
1986                 ADD     R3,R3,#4
1987                 STMIA   R10,{R0-R3}
1988
1989                 LDMFD   R13!,{R0-R10,R14}       ;Restore all the registers
1990                 B       brd3                    ;And plot the writable border
1991
1992                 LTORG
1993
1994
1995 ;----- Mangle coordinates for the mode --------------------------------------
1996
1997 ; --- box_convert ---
1998 ;
1999 ; Converts box given in R1-R4 by translating to screen coords and rounding
2000 ; down to pixel boundaries
2001
2002 box_convert     ROUT
2003
2004                 STMFD   R13!,{R0,R14}           ;Stash registers
2005
2006                 ; --- Convert to screen coordinates ---
2007
2008                 ADD     R1,R1,R9
2009                 ADD     R2,R2,R10
2010                 ADD     R3,R3,R9
2011                 ADD     R4,R4,R10
2012
2013                 ; --- Round off to whole pixel sizes ---
2014
2015                 LDR     R0,s_dx
2016                 LDR     R14,s_dy
2017                 SUB     R0,R0,#1
2018                 SUB     R14,R14,#1
2019                 BIC     R1,R1,R0
2020                 BIC     R2,R2,R14
2021                 BIC     R3,R3,R0
2022                 BIC     R4,R4,R14
2023                 LDMFD   R13!,{R0,PC}
2024
2025 ;----- Set up the VDU variables in the buffer -------------------------------
2026
2027 ; --- vdu_set ---
2028
2029 vdu_set         ROUT
2030
2031                 STMFD   R13!,{R0-R3,R14}        ;Stack some registers
2032                 ADR     R0,vdu_wanted           ;Which ones do we want?
2033                 ADR     R1,s_dx                 ;Where do we want them?
2034                 SWI     XOS_ReadVduVariables    ;Read the values
2035                 LDMIA   R1,{R0,R2}              ;Read their values into regs
2036                 CMP     R2,#2                   ;Is this a high-pixel mode?
2037                 MOVEQ   R3,#2                   ;Yes -- use a default value
2038                 MOVNE   R3,#4
2039                 MOVNE   R3,R3,LSR R2            ;No -- divide up border
2040                 RSBNE   R3,R3,#4
2041                 MOV     R14,#1
2042                 MOV     R0,R14,LSL R0           ;Convert these to pixel sizes
2043                 MOV     R2,R14,LSL R2
2044                 STMIA   R1,{R0,R2,R3}           ;Store back in workspace
2045                 LDMFD   R13!,{R0-R3,PC}^        ;Return to caller
2046
2047 vdu_wanted      DCD     vdu_XEIG
2048                 DCD     vdu_YEIG
2049                 DCD     -1
2050
2051                 LTORG
2052
2053 ;----- Plot primitives ------------------------------------------------------
2054
2055 ; --- prim_left ---
2056 ;
2057 ; Plots a vertical strip in the current foreground colour on the left of an
2058 ; icon box.
2059 ;
2060 ; On entry:     R0 == pointer to the icon bounding box
2061
2062 prim_left       ROUT
2063
2064                 STMFD   R13!,{R0-R3,R14}        ;Keep the stack pointer busy
2065                 MOV     R3,R0                   ;Keep the pointer safe
2066                 LDMIA   R3!,{R1,R2}             ;Get the bottom left coord
2067                 SUB     R1,R1,#4                ;Make way for the border
2068                 SUB     R2,R2,#4                ;Make way for the border
2069                 MOV     R0,#plot_MOVE+plot_ABSOLUTE
2070                 SWI     XOS_Plot                ;Move to first corner
2071                 LDR     R1,s_dx                 ;Get the pixel width
2072                 RSB     R1,R1,#4                ;Trim the width a little
2073                 LDR     R3,[R3,#4]              ;Get the top coordinate
2074                 SUB     R2,R3,R2                ;Find the height of the strip
2075                 LDR     R3,s_dy                 ;Get the y pixel size
2076                 SUB     R2,R2,R3                ;And add that in too
2077                 ADD     R2,R2,#4                ;And add the border width
2078                 MOV     R0,#plot_RECTFILL+plot_FORE+plot_RELATIVE
2079                 SWI     XOS_Plot                ;Plot the rectangle
2080                 LDMFD   R13!,{R0-R3,PC}^        ;Return to caller
2081
2082                 LTORG
2083
2084 ; --- prim_right ---
2085 ;
2086 ; Plots a vertical strip in the current foreground colour on the right of an
2087 ; icon box.
2088 ;
2089 ; On entry:     R0 == pointer to the icon bounding box
2090
2091 prim_right      ROUT
2092
2093                 STMFD   R13!,{R0-R3,R14}        ;Keep the stack pointer busy
2094                 ADD     R3,R0,#16               ;Point to the top of the box
2095                 LDMDB   R3!,{R1,R2}             ;Get the top right coord
2096                 LDR     R0,s_dy                 ;Get the y pixel size
2097                 SUB     R2,R2,R0
2098                 ADD     R2,R2,#4                ;Make way for the border
2099                 MOV     R0,#plot_MOVE+plot_ABSOLUTE
2100                 SWI     XOS_Plot                ;Move to first corner
2101                 LDR     R1,s_dx                 ;Get the pixel width
2102                 RSB     R1,R1,#4                ;Trim the width a little
2103                 LDR     R3,[R3,#-4]             ;Get the bottom coordinate
2104                 SUB     R2,R3,R2                ;Find the height of the strip
2105                 SUB     R2,R2,#4                ;And add the border width
2106                 MOV     R0,#plot_RECTFILL+plot_FORE+plot_RELATIVE
2107                 SWI     XOS_Plot                ;Plot the rectangle
2108                 LDMFD   R13!,{R0-R3,PC}^        ;Return to caller
2109
2110                 LTORG
2111
2112 ; --- prim_bottom ---
2113 ;
2114 ; Plots a horizontal strip in the current foreground colour along the bottom
2115 ; of an icon, with a little jagged bit on the left hand side.
2116 ;
2117 ; On entry:     R0 == pointer to icon block
2118
2119
2120 prim_bottom     ROUT
2121
2122                 STMFD   R13!,{R0-R2,R7-R11,R14} ;Keep stack pointer moving
2123
2124                 ; --- Load the variables we need ---
2125
2126                 LDMIA   R0,{R9-R11}             ;Get useful coordinates out
2127                 LDR     R1,s_dx                 ;Get x pixel width
2128                 LDR     R8,s_dy                 ;Get y pixel width
2129                 LDR     R2,s_start              ;Get start X offset
2130
2131                 ; --- Initialise variables for first loop ---
2132
2133                 SUB     R9,R9,R2                ;Shift x0 back a little
2134                 SUB     R11,R11,R1              ;Shift x1 past icon edge
2135                 SUB     R2,R10,R8               ;Move y below the icon
2136                 ADD     R11,R11,#4              ;And make space for border
2137                 RSB     R7,R8,#4                ;Loop stops when R7==0
2138
2139                 ; --- Draw a line (loop body) ---
2140
2141 00prim_bottom   MOV     R0,#plot_MOVE+plot_ABSOLUTE
2142                 MOV     R1,R9
2143                 SWI     XOS_Plot                ;Move to the left of the line
2144                 MOV     R0,#plot_LINE+plot_FORE+plot_ABSOLUTE
2145                 MOV     R1,R11
2146                 SWI     XOS_Plot                ;Draw the line
2147
2148                 ; --- Check if we've done (loop termination) ---
2149
2150                 SUBS    R7,R7,R8                ;Decrement the counter
2151                 LDMLTFD R13!,{R0-R2,R7-R11,PC}^ ;Return to caller
2152
2153                 ; --- Update coordinates (loop update) ---
2154
2155                 SUB     R9,R9,R8                ;Move x coordinate back a bit
2156                 SUB     R2,R2,R8                ;Move y coordinate down a bit
2157                 B       %00prim_bottom          ;And do it all again
2158
2159                 LTORG
2160
2161 ; --- prim_top ---
2162 ;
2163 ; Plots a horizontal strip in the current foreground colour along the top
2164 ; of an icon, with a little jagged bit on the right hand side.
2165 ;
2166 ; On entry:     R0 == pointer to icon block
2167
2168
2169 prim_top        ROUT
2170
2171                 STMFD   R13!,{R0-R2,R7-R11,R14} ;Keep stack pointer moving
2172
2173                 ; --- Load the variables we need ---
2174
2175                 LDMIA   R0,{R8-R11}             ;Get useful coordinates out
2176                 MOV     R9,R8                   ;Don't want y0
2177                 LDR     R1,s_dx                 ;Get x pixel width
2178                 LDR     R8,s_dy                 ;Get y pixel width
2179                 LDR     R2,s_start              ;Get start X offset
2180
2181                 ; --- Initialise variables for first loop ---
2182
2183                 SUB     R9,R9,#4                ;Make space for border
2184                 SUB     R10,R10,R1              ;Shift x1 past icon edge
2185                 ADD     R10,R10,R2              ;And add on the little bitty
2186                 MOV     R2,R11                  ;Move y above the icon
2187                 RSB     R7,R8,#4                ;Loop stops when R7==0
2188
2189                 ; --- Draw a line (loop body) ---
2190
2191 00prim_top      MOV     R0,#plot_MOVE+plot_ABSOLUTE
2192                 MOV     R1,R9
2193                 SWI     XOS_Plot                ;Move to the left of the line
2194                 MOV     R0,#plot_LINE+plot_FORE+plot_ABSOLUTE
2195                 MOV     R1,R10
2196                 SWI     XOS_Plot                ;Draw the line
2197
2198                 ; --- Check if we've done (loop termination) ---
2199
2200                 SUBS    R7,R7,R8                ;Decrement the counter
2201                 LDMLTFD R13!,{R0-R2,R7-R11,PC}^ ;Return to caller
2202
2203                 ; --- Update coordinates (loop update) ---
2204
2205                 ADD     R10,R10,R8              ;Move x coordinate on a bit
2206                 ADD     R2,R2,R8                ;Move y coordinate up a bit
2207                 B       %00prim_top             ;And do it all again
2208
2209                 LTORG
2210
2211 ;----- Workspace layout -----------------------------------------------------
2212
2213                 ^       0,R12
2214
2215 s_wstart        #       0
2216
2217                 ; --- Graphics variables ---
2218
2219 s_dx            #       4                       ;Horizontal pixel size (OS)
2220 s_dy            #       4                       ;Vertical pixel size (OS)
2221 s_start         #       4                       ;Offset into corner for plot
2222
2223                 ; --- Various other things ---
2224
2225 s_flags         #       4                       ;Various Sculptix flags
2226 s_sarea         #       4                       ;The sprite area in tns icons
2227
2228                 ; --- Colours ---
2229
2230 s_colours       #       4                       ;Colours for the 3D bits
2231 s_shadeCols     #       4                       ;Colours for shaded 3D boxes
2232 s_slabcol       #       1                       ;Slabbing in colour
2233 s_rimcol        #       1                       ;Inner rim colour for type 2
2234                 #       2                       ;Padding to align
2235
2236                 ; --- Misc buffers ---
2237
2238 s_buffer        #       256                     ;A big buffer for things
2239
2240 s_wend          #       0
2241
2242 s_UNSLAB        EQU     (1<<0)                  ;We've unslabbed this poll
2243 s_CHANNEL       EQU     (1<<1)                  ;Use channels, not ridges
2244 s_FAINTCHAN     EQU     (1<<2)                  ;Draw channel boxes faintly
2245
2246 s_wsize         EQU     s_wend-s_wstart
2247
2248 ;----- That's all, folks ----------------------------------------------------
2249
2250                 END