chiark / gitweb /
Initial revision
[ssr] / StraySrc / SapphToys / !ColDemo / s / rgb
1 ;
2 ; rgb.s
3 ;
4 ; Handling the RGB colour model dialogue box
5 ;
6 ; © 1994 Straylight
7 ;
8
9 ;----- Standard header ------------------------------------------------------
10
11                 GET     libs:header
12                 GET     libs:swis
13
14                 GET     libs:stream
15
16 ;----- External dependencies ------------------------------------------------
17
18                 GET     sapphire:dbox
19                 GET     sapphire:divide
20                 GET     sapphire:idle
21                 GET     sapphire:roVersion
22                 GET     sapphire:screen
23                 GET     sapphire:win
24
25                 GET     sapphire:dbx.dbx
26                 GET     sapphire:dbx.arrow
27                 GET     sapphire:dbx.numWrite
28                 GET     sapphire:dbx.slider
29
30                 GET     sapphire:_cs.kernel
31                 GET     sapphire:_cs.vars
32
33 ;----- Main code ------------------------------------------------------------
34
35                 AREA    |Sapphire$$Code|,CODE,READONLY
36
37 ; --- rgb_open ---
38 ;
39 ; On entry:     --
40 ;
41 ; On exit:      --
42 ;
43 ; Use:          Called by the colour picker
44
45                 EXPORT  rgb_open
46 rgb_open        ROUT
47
48                 STMFD   R13!,{R1-R3,R14}        ;Stack the link register
49                 ADR     R0,rgb__dbName          ;Point to dialogue box name
50                 BL      dbox_create             ;Create the dialogue box
51                 LDMVSFD R13!,{R1-R3,PC}         ;Return now if it failed
52                 STR     R0,[R13,#-4]!           ;Return dialogue handle in R0
53
54                 ; --- Attach event handlers and things ---
55
56                 ADR     R1,rgb__dbHandler       ;Point to my handler code
57                 MOV     R2,R10                  ;Pass colour workspace in R10
58                 MOV     R3,R12                  ;Pass my workspace in R12
59                 BL      dbox_eventHandler       ;Register my event handler
60                 ADR     R1,rgb__dbxDef          ;Point to the control defn
61                 BL      dbx_declare             ;Declare it to dbx nicely
62
63                 ; --- Set up the workspace ---
64
65                 MOV     R0,#0                   ;Set the Red mapping
66                 BL      rgb__setMapping         ;Set this as the mapping
67
68                 ; --- Set up the dialogue box ---
69
70                 LDR     R0,[R13,#0]             ;Load the dialogue handle
71                 LDR     R1,rgb__mapping         ;Get the current mapping
72                 ADD     R1,R1,R1,LSL #2         ;Multiply by icon offset (5)
73                 ADD     R1,R1,#rgbIcon__radioR  ;Add on to get icon number
74                 MOV     R2,#1                   ;Please select this icon
75                 BL      dbox_select             ;Select the right one
76
77                 MOV     R1,#rgbIcon__writeR     ;Get the red writable icon
78                 LDR     R2,rgb__red             ;Find the red value
79                 LDR     R2,[R2,#0]              ;Load the red value
80                 BL      numWrite_set            ;Set it in the icon
81
82                 MOV     R1,#rgbIcon__writeG     ;Get the green writable icon
83                 LDR     R2,rgb__green           ;Find the green value
84                 LDR     R2,[R2,#0]              ;Load the green value
85                 BL      numWrite_set            ;Set it in the icon
86
87                 MOV     R1,#rgbIcon__writeB     ;Get the blue writable icon
88                 LDR     R2,rgb__blue            ;Find the blue value
89                 LDR     R2,[R2,#0]              ;Load the blue value
90                 BL      numWrite_set            ;Set it in the icon
91                 LDMFD   R13!,{R0-R3,R14}        ;Return to caller
92
93 rgb__dbName     DCB     "rgb",0
94
95 rgb__dbxDef     CONTROL rgbIcon__square,rgbSquare,R10,0,0
96                 ECTRL
97
98                 SLIDER  rgbIcon__slide1,R10,:INDEX: rgb__sl1Val,                                        slFlag_horizontal + slFlag_colData,0,0,1,100
99                 NUMWRT  rgbIcon__writeR,0,100
100                 ARROW   rgbIcon__upR,1
101                 ARROW   rgbIcon__downR,-1
102
103                 SLIDER  rgbIcon__slide2,R10,:INDEX: rgb__sl2Val,                                        slFlag_vertical + slFlag_colData,0,0,1,100
104                 NUMWRT  rgbIcon__writeG,0,100
105                 ARROW   rgbIcon__upG,1
106                 ARROW   rgbIcon__downG,-1
107
108                 SLIDER  rgbIcon__slide3,R10,:INDEX: rgb__sl3Val,                                        slFlag_vertical + slFlag_colData,0,0,1,100
109                 NUMWRT  rgbIcon__writeB,0,100
110                 ARROW   rgbIcon__upB,1
111                 ARROW   rgbIcon__downB,-1
112
113                 DBXEND
114
115 ; --- rgb__dbHandler ---
116 ;
117 ; On entry:     R0 == dialogue box event code
118 ;               R1-R7 == depend on the event
119 ;               R9 == dialogue box handle of RGB panel
120 ;               R10 == pointer to colour selector workspace
121 ;               R12 == nothing much
122 ;
123 ; On exit:      --
124 ;
125 ; Use:          Handles events for the RGB panel.
126
127 rgb__dbHandler  ROUT
128
129                 ; --- Dispatch events to their destinations ---
130
131                 CMP     R0,#rgbIcon__radioR     ;Is it the red view button?
132                 CMPNE   R0,#rgbIcon__radioG     ;Or the green view button?
133                 CMPNE   R0,#rgbIcon__radioB     ;Or the blue view button?
134                 BEQ     rgb__setView            ;Yes -- set the new view
135
136                 CMP     R0,#csEvent__close      ;Is it a close panel event?
137                 BEQ     rgb__closePanel         ;Yes -- destroy the dialogue
138
139                 CMP     R0,#csEvent__newRes     ;Is it a resolution change?
140                 BEQ     rgb__newRes             ;Yes -- update the piccy then
141
142                 CMP     R0,#slider_event        ;Is it a slider event?
143                 BEQ     rgb__slChange           ;Yes -- do something then
144
145                 CMP     R0,#numWrite_event      ;Is it a writable event?
146                 BEQ     rgb__wrChange           ;Yes -- do something then
147
148                 CMP     R0,#arrow_event         ;Is it an arrow event?
149                 BEQ     rgb__arChange           ;Yes -- do something then
150
151                 STMFD   R13!,{R14}              ;Save a register
152                 SUB     R14,R0,#rgbIcon__wCols  ;Is it a WIMP colour box?
153                 CMP     R14,#16                 ;Check it's in range
154                 BLO     rgb__wimpCol            ;Yes -- handle it then
155
156                 LDMFD   R13!,{PC}^              ;Unknown -- return to caller
157
158                 ; --- Change the panel view ---
159
160 rgb__setView    ROUT
161
162                 STMFD   R13!,{R0-R3,R14}        ;Save some registers
163                 CMP     R0,#rgbIcon__radioG     ;Is it the green button?
164                 MOVLT   R3,#0                   ;Lower -- it must be red
165                 MOVEQ   R3,#1                   ;Equal -- must be green
166                 MOVGT   R3,#2                   ;Greater -- must be blue
167                 LDR     R1,rgb__mapping         ;Get the current mapping
168                 CMP     R3,R1                   ;Is it the same?
169                 LDMEQFD R13!,{R0-R3,PC}^        ;Yes -- return now then
170
171                 ; --- Select the correct icon ---
172
173                 MOV     R0,R9                   ;Load the dialogue handle
174                 ADD     R1,R1,R1,LSL #2         ;Multiply by icon offset (5)
175                 ADD     R1,R1,#rgbIcon__radioR  ;Add on to get icon number
176                 MOV     R2,#0                   ;Please deselect this icon
177                 BL      dbox_select             ;Select the right one
178
179                 ADD     R1,R3,R3,LSL #2         ;Multiply by icon offset (5)
180                 ADD     R1,R1,#rgbIcon__radioR  ;Add on to get icon number
181                 MOV     R2,#1                   ;Please select this icon
182                 BL      dbox_select             ;Select the right one
183
184                 ; --- Update the dialogue box sliders etc. ---
185
186                 MOV     R0,R9                   ;Get the dialogue box handle
187                 MOV     R1,#rgbIcon__square     ;Get the colour square
188                 BL      dbx_qUpdate             ;Get rid of the crosshair
189                 MOV     R0,R3                   ;Pass mapping number
190                 BL      rgb__setMapping         ;Redo all the mappings
191                 BL      rgb__updateSliders      ;And redraw the sliders
192                 MOV     R0,R9                   ;Get the dialogue box handle
193                 MOV     R1,#rgbIcon__square     ;Get the colour square
194                 BL      dbx_update              ;Redraw it nicely
195                 LDMFD   R13!,{R0-R3,PC}^        ;Return to caller
196
197                 ; --- Update the RGB colour cube view ---
198
199 rgb__newRes     ROUT
200
201                 STMFD   R13!,{R0,R1,R14}        ;Save some registers
202                 MOV     R0,R9                   ;Get the dialogue handle
203                 MOV     R1,#rgbIcon__square     ;Get the colour square
204                 BL      dbx_qUpdate             ;Get rid of the crosshair
205                 BL      dbx_update              ;Redraw it nicely
206                 LDMFD   R13!,{R0,R1,PC}^        ;And return to caller
207
208                 ; --- Update colour values ---
209
210 rgb__slChange   ROUT
211
212                 STMFD   R13!,{R0-R2,R4,R14}     ;Save some registers
213
214                 ; --- Update the main dialogue's colour pot ---
215
216                 BL      rgb__colUpdate          ;Update the colour pot
217
218                 ; --- Now update the writable icon ---
219
220                 LDR     R2,[R13,#8]             ;Load the slider icon
221                 SUB     R4,R2,#rgbIcon__slide1  ;Get the slider axis number
222                 LDR     R14,rgb__mapping        ;Load the mapping number
223                 SUB     R1,R14,R4               ;Find the table index
224                 ADR     R14,rgb__writeTbl+2     ;Point to the table
225                 LDRB    R1,[R14,R1]             ;Load the icon number
226                 MOV     R0,R9                   ;Put dialogue handle in R0
227                 MOV     R2,R3                   ;Put slider value in R2
228                 BL      numWrite_set            ;And put it in the icon
229
230                 ; --- Now work out what else to update ---
231
232                 CMP     PC,#0                   ;Clear the Z flag
233                 BL      cs_immediate            ;Are we doing immediate ops?
234                 LDRCC   R14,[R13,#4]            ;Load the subreason code
235                 CMPCC   R14,#slider_sliding     ;Is the slider going still?
236                 BLNE    rgb__zUpdate            ;No -- redraw colour square
237
238                 BL      rgb__xyUpdate           ;Now move the crosshair
239
240 90rgb__slChange LDMFD   R13!,{R0-R2,R4,PC}^     ;Return to caller
241
242 rgb__writeTbl   DCB     rgbIcon__writeR
243                 DCB     rgbIcon__writeG
244                 DCB     rgbIcon__writeB
245                 DCB     rgbIcon__writeR
246                 DCB     rgbIcon__writeG
247
248                 ; --- He typed something into one of our icons ---
249
250 rgb__wrChange   ROUT
251
252                 STMFD   R13!,{R0-R5,R14}        ;Save some registers
253
254                 ; --- First, find the value this writable applies to ---
255
256                 CMP     R1,#rgbIcon__writeG     ;Which writable icon is it?
257                 MOVLT   R1,#0                   ;Red -- remember this map
258                 MOVEQ   R1,#1                   ;Green -- remember this
259                 MOVGT   R1,#2                   ;Blue -- remember this
260                 ADR     R14,rgb__red            ;Point to the mappings
261                 LDR     R14,[R14,R1,LSL #2]     ;Translate the colour
262                 LDR     R0,[R14,#0]             ;Load the actual value
263                 SUBS    R5,R0,R3                ;Is this our value?
264
265                 ; --- He's changed the value -- update slider/colour ---
266
267                 STRNE   R3,[R14,#0]             ;Save the new value away
268                 BLNE    rgb__colUpdate          ;Redraw the colour pot
269                 LDR     R0,rgb__mapping         ;Load the mapping number
270                 SUB     R3,R1,R0                ;Work out the table index
271                 ADR     R14,rgb__slideTbl+2     ;Point to slider icon table
272                 LDRB    R1,[R14,R3]             ;Load the icon number
273                 LDR     R0,cs__modelDb          ;Load the panel dialogue
274                 BLNE    dbx_update              ;Redraw the slider nicely
275
276                 ; --- Update the main piccy ---
277
278                 CMPEQ   PC,#0                   ;Clear the Z flag
279                 BL      cs_immediate            ;Are we doing immediate ops?
280                 CMPCC   R2,#numWrite_change     ;Is he just typing numbers?
281                 BLNE    rgb__zUpdate            ;No -- redraw colour square
282
283                 BL      rgb__xyUpdate           ;Now move the crosshair
284
285 90rgb__wrChange LDMFD   R13!,{R0-R5,PC}^        ;Return to caller
286
287 rgb__slideTbl   DCB     rgbIcon__slide2
288                 DCB     rgbIcon__slide1
289                 DCB     rgbIcon__slide3
290                 DCB     rgbIcon__slide2
291                 DCB     rgbIcon__slide1
292
293 rgb__arChange   ROUT
294
295                 STMFD   R13!,{R0-R4,R14}        ;Save some registers
296                 MOV     R4,R2                   ;Look after the bump
297
298                 ; --- First, find the value this arrow applies to ---
299
300                 CMP     R1,#rgbIcon__upG        ;Which writable icon is it?
301                 CMPGT   R1,#rgbIcon__downG      ;There's two for green
302                 MOVLT   R3,#0                   ;Red -- remember this map
303                 MOVEQ   R3,#1                   ;Green -- remember this
304                 MOVGT   R3,#2                   ;Blue -- remember this
305
306                 ; --- Now bump the required writable icon ---
307
308                 ADR     R14,rgb__writeTbl       ;Point to the icon table
309                 LDRB    R1,[R14,R3]             ;Load the correct icon
310                 MOV     R0,R9                   ;Pass dialogue in R0
311                 BL      numWrite_bump           ;Apply the bump value
312
313                 ; --- Now perform the update operation ---
314
315                 CMPEQ   PC,#0                   ;Clear the Z flag
316                 BL      cs_immediate            ;Are we doing immediates?
317                 TEQCS   R4,#0                   ;And is the bump sensible?
318                 BEQ     %90rgb__arChange        ;Immediate/end ==> return
319                 MOV     R3,R2                   ;Get value in R3 nicely
320                 MOVCS   R2,#1                   ;Update always if immediate
321                 MOVCC   R2,#0                   ;Default is no update if not
322                 TEQ     R4,#0                   ;And is the bump sensible?
323                 MOVEQ   R2,#1                   ;No -- then force update
324                 BL      rgb__wrChange           ;Handle writable update then
325
326 90rgb__arChange LDMFD   R13!,{R0-R4,PC}^        ;And return to caller
327
328                 LTORG
329
330                 ; --- Close the panel to open a new one ---
331
332 rgb__closePanel ROUT
333
334                 STMFD   R13!,{R0,R14}           ;Save some registers
335                 MOV     R0,R9                   ;Get the dialogue handle
336                 BL      dbox_destroy            ;Kill off the dialogue
337                 LDMFD   R13!,{R0,PC}^           ;And return to caller
338
339                 ; --- Handle a click on one of the WIMP colours ---
340                 ;
341                 ; The WIMP colour number resides in R14 at the moment :-/
342
343 rgb__wimpCol    ROUT
344
345                 STMFD   R13!,{R0,R1}            ;Save some registers
346                 SUB     R13,R13,#80             ;Make space for palette block
347                 MOV     R1,R13                  ;Point to my block
348                 SWI     Wimp_ReadPalette        ;Read the WIMP palette
349                 LDR     R1,[R13,R14,LSL #2]     ;Load the one we want
350                 ADD     R13,R13,#80             ;Don't need this now
351
352                 ; --- Under RISC OS <3.50, bodge palette entry ---
353                 ;
354                 ; Because of Acorn stupidity, the ReadPalette values have
355                 ; blank lower nibbles.  According to Acorn, I must copy the
356                 ; top nibbles into the bottom ones for ColourTrans to be
357                 ; happy.  I assume that this has been sorted out on 3.50 and
358                 ; later.
359
360                 BL      rov_version             ;Get the RISC OS version
361                 CMP     R0,#340                 ;It's almost 350 :-)
362                 LDRLO   R14,=&F0F0F000          ;A nibble mask
363                 ANDLO   R1,R1,R14               ;Clear bottom nibbles
364                 ORRLO   R1,R1,R1,LSR #4         ;And duplicate top in bottom
365
366                 STR     R1,cs__colour+col_rgb   ;Save this new colour
367                 BL      rgb__setValues          ;And redo everything nicely
368                 LDMFD   R13!,{R0,R1,PC}^        ;And return to caller
369
370                 LTORG
371
372 ; --- rgb__setValues ---
373 ;
374 ; On entry:     R10 == address of colour selector instance data
375 ;
376 ; On exit:      --
377 ;
378 ; Use:          Updates all the values in the dialogue box from the colour
379 ;               word in the workspace (which is assumed to have changed).
380 ;               The colour mapping is assumed to still be valid, though.
381
382 rgb__setValues  ROUT
383
384                 STMFD   R13!,{R0-R2,R14}        ;Save some registers
385
386                 ; --- Unpack the value from the colour RGB word ---
387
388                 BL      rgb__unpack             ;Get the percentages out
389
390                 ; --- Do the writable icons ---
391
392                 LDR     R0,cs__modelDb          ;Get the dialogue handle
393                 MOV     R1,#rgbIcon__writeR     ;Get the red writable icon
394                 LDR     R2,rgb__red             ;Find the red value
395                 LDR     R2,[R2,#0]              ;Load the red value
396                 BL      numWrite_set            ;Set it in the icon
397
398                 MOV     R1,#rgbIcon__writeG     ;Get the green writable icon
399                 LDR     R2,rgb__green           ;Find the green value
400                 LDR     R2,[R2,#0]              ;Load the green value
401                 BL      numWrite_set            ;Set it in the icon
402
403                 MOV     R1,#rgbIcon__writeB     ;Get the blue writable icon
404                 LDR     R2,rgb__blue            ;Find the blue value
405                 LDR     R2,[R2,#0]              ;Load the blue value
406                 BL      numWrite_set            ;Set it in the icon
407
408                 ; --- Now do the other controls ---
409
410                 BL      rgb__updateSliders      ;Do the slider update
411                 BL      cs_colChange            ;Redraw main colour pot
412                 BL      rgb__zUpdate            ;Force a recache of z
413                 BL      rgb__xyUpdate           ;And a recache of x and y
414                 LDMFD   R13!,{R0-R2,PC}^        ;And return to caller
415
416                 LTORG
417
418 ; --- rgb__updateSliders ---
419 ;
420 ; On entry:     R10 == address of colour selector instance data
421 ;
422 ; On exit:      --
423 ;
424 ; Use:          Redraws all the sliders.  Because the slider code is so
425 ;               amazingly intelligent, if the values haven't changed, the
426 ;               picture you see won't change either.
427
428 rgb__updateSliders ROUT
429
430                 STMFD   R13!,{R0,R1,R14}        ;Save some registers
431                 LDR     R0,cs__modelDb          ;Get the dialogue handle
432                 MOV     R1,#rgbIcon__slide1     ;Get slider 1's number
433                 BL      dbx_update              ;Redraw it quickly
434                 MOV     R1,#rgbIcon__slide2     ;Get slider 2's number
435                 BL      dbx_update              ;Redraw it quickly
436                 MOV     R1,#rgbIcon__slide3     ;Get slider 3's number
437                 BL      dbx_update              ;Redraw it quickly
438                 LDMFD   R13!,{R0,R1,PC}^        ;And return to caller
439
440                 LTORG
441
442 ; --- rgb__setMapping ---
443 ;
444 ; On entry:     R0 == rotation number (i.e. which colour is on z azis)
445 ;
446 ; On exit:      --
447 ;
448 ; Use:          Sets up the workspace so that the dialogue box displays the
449 ;               correct mapping.
450
451 rgb__setMapping ROUT
452
453                 STMFD   R13!,{R0-R3,R14}        ;Save some registers
454
455                 ; --- Reset the mapping number and table ---
456
457                 STR     R0,rgb__mapping         ;Save the mapping number
458                 ADR     R1,rgb__mappingTbl      ;Point to the table
459                 ADD     R1,R1,R0                ;Index it nicely
460
461                 LDRB    R14,[R1],#1             ;Load the blue offset
462                 ADD     R14,R10,R14             ;Add it to workspace ptr
463                 STR     R14,rgb__blue           ;And store nicely
464                 MOV     R2,#8                   ;The blue slider colour
465                 STR     R2,[R14,#4]             ;Save it in the table
466
467                 LDRB    R14,[R1],#1             ;Load the green offset
468                 ADD     R14,R10,R14             ;Add it to workspace ptr
469                 STR     R14,rgb__green          ;And store nicely
470                 MOV     R2,#10                  ;The green slider colour
471                 STR     R2,[R14,#4]             ;Save it in the table
472
473                 LDRB    R14,[R1],#1             ;Load the red offset
474                 ADD     R14,R10,R14             ;Add it to workspace ptr
475                 STR     R14,rgb__red            ;And store nicely
476                 MOV     R2,#11                  ;The red slider colour
477                 STR     R2,[R14,#4]             ;Save it in the table
478
479                 BL      rgb__unpack             ;Unpack colour def now
480
481                 ; --- Set up the cached values for the diagram ---
482
483                 LDR     R14,rgb__sl1Val         ;Load the x value
484                 STR     R14,rgb__xPos           ;Save it in the cache
485                 LDR     R14,rgb__sl2Val         ;Load the y value
486                 STR     R14,rgb__yPos           ;Save it in the cache
487                 LDR     R14,rgb__sl3Val         ;Load the z value
488                 STR     R14,rgb__zPos           ;Save it in the cache
489
490                 LDMFD   R13!,{R0-R3,PC}^        ;Return to caller
491
492                 LTORG
493
494                 ; --- The mapping table ---
495                 ;
496                 ; The table is done twice, to give it a `wraparound' effect.
497
498 rgb__mappingTbl DCB     :INDEX: rgb__sl1Val
499                 DCB     :INDEX: rgb__sl2Val
500                 DCB     :INDEX: rgb__sl3Val
501                 DCB     :INDEX: rgb__sl1Val
502                 DCB     :INDEX: rgb__sl2Val
503
504 ; --- rgb__unpack ---
505 ;
506 ; On entry:     R10 == address of colour selector instance data
507 ;
508 ; On exit:      --
509 ;
510 ; Use:          Unpacks the colour definition in the cs data into the
511 ;               slider values.
512
513 rgb__unpack     ROUT
514
515                 STMFD   R13!,{R0-R2,R14}        ;Save some workspace
516                 LDR     R2,cs__colour+col_rgb   ;Get the colour nicely
517
518                 ; --- Set up the blue slider ---
519
520                 MOV     R0,R2,LSR #24           ;Get the blue colour value
521                 BL      rgb__colToPerC          ;Convert it to a percentage
522                 LDR     R14,rgb__blue           ;Load the blue entry address
523                 STR     R0,[R14]                ;Save the blue value in it
524
525                 ; --- Now set up the green one ---
526
527                 MOV     R0,R2,LSR #16           ;Get the green colour value
528                 BL      rgb__colToPerC          ;Convert it to a percentage
529                 LDR     R14,rgb__green          ;Load the green entry address
530                 STR     R0,[R14]                ;Save the green value in it
531
532                 ; --- Now set up the red one ---
533
534                 MOV     R0,R2,LSR #8            ;Get the red colour value
535                 BL      rgb__colToPerC          ;Convert it to a percentage
536                 LDR     R14,rgb__red            ;Load the red entry address
537                 STR     R0,[R14]                ;Save the red value in it
538                 LDMFD   R13!,{R0-R2,PC}^        ;And return to caller
539
540                 LTORG
541
542 ; --- rgb__colToPerC ---
543 ;
544 ; On entry:     R0 == colour to convert, from 0 to 255
545 ;
546 ; On exit:      R0 == colour as a percentage
547 ;
548 ; Use:          Converts a colour to a percentage.
549 ;
550 ; [Generated by Straylight divc]
551 ; Modified by MDW to (a) be unsigned, and (b) round to nearest.
552
553 rgb__colToPerC  ROUT
554
555                 STMFD   R13!,{R1,R14}           ;Save some registers
556                 AND     R0,R0,#&FF              ;Mask off any other bits
557                 ADD     R0,R0,R0,LSL #2         ;Multiply by 5 (x5)
558                 ADD     R0,R0,R0,LSL #2         ;And by 5 again (x25)
559                 MOV     R0,R0,LSL #2            ;And now by 4 (x100)
560                 MOV     R1,R0                   ;Keep copy of dividend
561                 ADD     R0,R0,#127              ;Make it round to nearest
562                 ADD     R0,R0,R0,LSR #8         ;R0 = R0 x 256/255
563                 ADD     R0,R0,R0,LSR #16        ;...
564                 MOV     R0,R0,LSR #8            ;Div by 256 -- R0 = R0 / 255
565                 RSB     R14,R0,R0,LSL #8        ;Multiply by 255
566                 SUB     R1,R1,R14               ;Find the difference
567                 SUBS    R1,R1,#255              ;This is the remainder
568                 ADDGE   R0,R0,#1                ;If we overshot, bump quot
569                 ADDLT   R1,R1,#255              ;And chop off remainder
570                 LDMFD   R13!,{R1,PC}^           ;Return to caller
571
572                 LTORG
573
574 ; --- rgb__perCToCol ---
575 ;
576 ; On entry:     R0 == colour percentage to convert
577 ;
578 ; On exit:      R0 == colour value, from 0-255
579 ;
580 ; Use:          Converts a percentage to a colour.
581
582 rgb__perCToCol  ROUT
583
584                 STMFD   R13!,{R1,R14}           ;Save some registers
585                 RSB     R0,R0,R0,LSL #8         ;Multiply it by 255
586                 ADD     R0,R0,#50               ;Add 50 to round to nearest
587                 BL      div10                   ;Divide by 10
588                 BL      div10                   ;And again (by 100)
589                 LDMFD   R13!,{R1,PC}^           ;And return to caller
590
591                 LTORG
592
593 ; --- rgb__colUpdate ---
594 ;
595 ; On entry:     --
596 ;
597 ; On exit:      --
598 ;
599 ; Use:          Updates the main dialogue's colour pot.
600
601 rgb__colUpdate  ROUT
602
603                 STMFD   R13!,{R0,R2,R14}        ;Save some registers
604                 MOV     R2,#0                   ;Clear prospective colour
605
606                 LDR     R0,rgb__blue            ;Get the blue colour address
607                 LDR     R0,[R0,#0]              ;Load the blue percentage
608                 BL      rgb__perCToCol          ;Convert it to a real colour
609                 ORR     R2,R2,R0,LSL #24        ;Move into R2 nicely
610
611                 LDR     R0,rgb__green           ;Get the green colour address
612                 LDR     R0,[R0,#0]              ;Load the green percentage
613                 BL      rgb__perCToCol          ;Convert it to a real colour
614                 ORR     R2,R2,R0,LSL #16        ;Move into R2 nicely
615
616                 LDR     R0,rgb__red             ;Get the red colour address
617                 LDR     R0,[R0,#0]              ;Load the red percentage
618                 BL      rgb__perCToCol          ;Convert it to a real colour
619                 ORR     R2,R2,R0,LSL #8         ;Move into R2 nicely
620
621                 STR     R2,cs__colour+col_rgb   ;Save this as the new colour
622                 LDMFD   R13!,{R0,R2,R14}        ;Restore registers
623                 B       cs_colChange            ;Update the main box's colour
624
625                 LTORG
626
627 ; --- rgb__zUpdate ---
628 ;
629 ; On entry:     --
630 ;
631 ; On exit:      --
632 ;
633 ; Use:          Updates everything following a change to the current z
634 ;               value.  It doesn't change the writable icon, but it does
635 ;               most other things.
636
637 rgb__zUpdate    ROUT
638
639                 STMFD   R13!,{R0-R2,R14}        ;Save some registers
640
641                 ; --- Make sure that the z coordinate changed ---
642
643                 LDR     R2,rgb__sl3Val          ;Load current z slider pos
644                 LDR     R0,rgb__zPos            ;Load the cached position
645                 CMP     R0,R2                   ;Do they match?
646                 LDMEQFD R13!,{R0-R2,PC}^        ;Yes -- nothing doing then
647
648                 ; --- Remove crosshairs -- it looks nicer ---
649
650                 LDR     R0,cs__modelDb          ;Load the model dialogue
651                 MOV     R1,#rgbIcon__square     ;Get the colour square
652                 BL      dbx_qUpdate             ;Get rid of the crosshair
653
654                 ; --- Now recache the x and y coords to prevent flicker ---
655
656                 STR     R2,rgb__zPos            ;Update the cache value
657                 LDR     R14,rgb__sl1Val         ;Load the current x value
658                 STR     R14,rgb__xPos           ;Save it away
659                 LDR     R14,rgb__sl2Val         ;Load the current y value
660                 STR     R14,rgb__yPos           ;Save it away
661
662                 ; --- Redraw the main square ---
663
664                 BL      dbx_update              ;Force a redraw of it
665                 LDMFD   R13!,{R0-R2,PC}^        ;And return to caller
666
667                 LTORG
668
669 ; --- rgb__xyUpdate ---
670 ;
671 ; On entry:     --
672 ;
673 ; On exit:      --
674 ;
675 ; Use:          Updates things following a change to either the x or y
676 ;               value.
677
678 rgb__xyUpdate   ROUT
679
680                 STMFD   R13!,{R0-R3,R14}        ;Save some registers
681                 LDR     R0,rgb__xPos            ;Load cached x position
682                 LDR     R1,rgb__yPos            ;Load cached y position
683                 LDR     R2,rgb__sl1Val          ;And the current x pos
684                 LDR     R3,rgb__sl2Val          ;And the current y pos
685                 CMP     R0,R2                   ;Is the cached x right?
686                 CMPEQ   R1,R3                   ;And is the cached y right?
687                 LDMEQFD R13!,{R0-R3,PC}^        ;Yes -- return then
688
689                 LDR     R0,cs__modelDb          ;Load the dialogue box handle
690                 MOV     R1,#rgbIcon__square     ;Load the square icon
691                 BL      dbx_qUpdate             ;Quickly redraw it
692                 STR     R2,rgb__xPos            ;Recache the x position
693                 STR     R3,rgb__yPos            ;Recache the y position
694                 BL      dbx_qUpdate             ;Quickly redraw it
695                 LDMFD   R13!,{R0-R3,PC}^        ;Return to caller
696
697                 LTORG
698
699 ;----- Plotting the colour square -------------------------------------------
700
701 ; --- rgb_plotSquare ---
702 ;
703 ; On entry:     R0 == left hand side of colour square to plot
704 ;               R1 == bottom edge of colour square to plot
705 ;               R2 == which rotation we're plotting
706 ;               R3 == x step to plot in
707 ;               R4 == y step to plot in
708 ;               R5 == z-coordinate value (in 16.16 form)
709 ;               R6 == pointer to graphics window block
710 ;
711 ; On exit:      --
712 ;
713 ; Use:          Plots a cross-section through the RGB colour cube.
714
715                 EXPORT  rgb_plotSquare
716 rgb_plotSquare  ROUT
717
718                 STMFD   R13!,{R0-R12,R14}       ;Save a job-lot of registers
719
720                 ; --- Work out the minimum coordinates ---
721
722                 LDMIA   R6,{R8,R9,R11,R12}      ;Load the coordinates out
723                 SUB     R7,R12,R1               ;Translate max y to relative
724                 SUB     R12,R9,R1               ;Translate min y too
725                 SUB     R10,R8,R0               ;Translate min x too
726                 SUB     R11,R11,R0              ;Translate max x
727
728                 ; --- See if we can do really clever things ---
729
730                 STMFD   R13!,{R0,R11}           ;Save our R11 value
731                 LDR     R11,[R13,#52]           ;Load the system R11 value
732                 BL      screen_getInfo          ;Load the screen information
733                 MOV     R8,R0                   ;Look after this address
734                 LDMFD   R13!,{R0,R11}           ;Reload our local value
735                 LDR     R14,[R8,#screen_bpp]    ;Load current bits/pixel
736                 CMP     R14,#16                 ;Is this a 2byte/pixel mode?
737                 BEQ     rgb__plot32k            ;Yes -- branch to special bit
738                 CMP     R14,#32                 ;Is this a 4byte/pixel mode?
739                 BEQ     rgb__plot16m            ;Yes -- branch to special bit
740
741                 ; --- Work out rectangle edges ---
742
743                 CMP     R10,#0                  ;Is min x too small?
744                 MOVLT   R10,#0                  ;Yes -- raise it to 0
745                 CMP     R12,#0                  ;Is min y too small?
746                 MOVLT   R12,#0                  ;Yes --- raise that too
747                 CMP     R11,#255                ;Is the max x too large?
748                 MOVGT   R11,#255                ;Yes -- reduce it then
749                 CMP     R7,#255                 ;Is the max y too large?
750                 MOVGT   R7,#255                 ;Yes -- reduce it then
751
752                 SUB     R8,R3,#1                ;Turn the x step to bitmask
753                 SUB     R9,R4,#1                ;And the same for y step
754                 BIC     R10,R10,R8              ;Round min x down to step
755                 BIC     R12,R12,R9              ;And round min y down too
756                 BIC     R11,R11,R8              ;Round max x down too
757                 BIC     R7,R7,R9                ;And round down max y
758
759                 STMFD   R13!,{R7,R10}           ;Save rel. min x and max y
760
761                 ADD     R10,R10,R0              ;Now make min x absolute
762                 ADD     R12,R12,R1              ;And make min y absolute
763                 ADD     R11,R11,R0              ;And make max x absolute
764                 ADD     R7,R7,R1                ;And make max y absolute
765
766                 ; --- Now work out the z-value ---
767
768                 RSB     R5,R5,R5,LSL #8         ;Multiply value by 255
769                 ADD     R5,R5,#&8000            ;Make sure we round nicely
770                 MOV     R5,R5,LSR #16           ;And make it 0-255
771
772                 ; --- Work out the exclusive rectangle sizes ---
773
774                 STMFD   R13!,{R11}              ;Save our R11 value
775                 LDR     R11,[R13,#56]           ;Load the system R11 value
776                 BL      screen_getInfo          ;Load the screen information
777                 LDMFD   R13!,{R11}              ;Reload our local value
778
779                 LDMIA   R0,{R8,R9}              ;Load the eigen factors out
780                 MOV     R14,#1                  ;This will be shifted around
781                 SUB     R8,R3,R14,LSL R8        ;Subtract x pixel from x step
782                 SUB     R9,R4,R14,LSL R9        ;Subtract y pixel from y step
783
784                 ; --- Work out all the shift values ---
785
786                 CMP     R2,#0                   ;Is this the red rotation?
787                 MOVEQ   R0,#24                  ;Yes -- then x is blue
788                 MOVEQ   R1,#16                  ;And y is green
789                 MOVEQ   R5,R5,LSL #8            ;And z is red
790
791                 CMP     R2,#1                   ;Is this the green rotation?
792                 MOVEQ   R0,#8                   ;Yes -- then x is red
793                 MOVEQ   R1,#24                  ;And y is blue
794                 MOVEQ   R5,R5,LSL #16           ;And z is green
795
796                 CMP     R2,#2                   ;Is this the blue rotation?
797                 MOVEQ   R0,#16                  ;Yes -- then x is green
798                 MOVEQ   R1,#8                   ;And y is red
799                 MOVEQ   R5,R5,LSL #24           ;And z is blue
800
801                 ; --- Set up the initial palette word ---
802
803                 LDMFD   R13!,{R14}              ;Load maximum y palette val
804                 ORR     R5,R5,R14,LSL R1        ;Fit that into the palette
805
806                 LDMFD   R13!,{R2}               ;Load minimum x palette val
807
808                 ; --- Now for the main plotting loop ---
809
810 00              MOV     R6,R10                  ;Start on the left hand side
811                 MOV     R14,#255                ;Clear out nasty x palette
812                 BIC     R5,R5,R14,LSL R0        ;Clear out the right byte
813                 ORR     R5,R5,R2,LSL R0         ;And set up the min value
814
815                 ; --- Plot the rectangle nicely ---
816
817 10              STMFD   R13!,{R0-R4}            ;Save some registers for this
818
819                 ; --- Nothing for it but to use ColourTrans ---
820                 
821                 MOV     R0,R5                   ;Get the palette entry
822                 MOV     R3,#&100                ;Please try to dither it
823                 MOV     R4,#0                   ;And have normal GCOL action
824                 SWI     XColourTrans_SetGCOL    ;Try to set the colour up
825                 MOVVS   R3,#0                   ;Try again without dithering
826                 MOVVS   R0,R5                   ;Set the palette word again
827                 SWIVS   ColourTrans_SetGCOL     ;Set the colour the old way
828
829 15              MOV     R0,#4                   ;Move cursor absolute
830                 MOV     R1,R6                   ;Get the current x coordinate
831                 MOV     R2,R7                   ;And the current y coordinate
832                 SWI     OS_Plot                 ;Move the cursor there
833                 MOV     R0,#97                  ;Rectangle fill relative
834                 MOV     R1,R8                   ;Rectangle width thingy
835                 MOV     R2,R9                   ;Rectangle height thingy
836                 SWI     OS_Plot                 ;Plot the rectangle
837                 LDMFD   R13!,{R0-R4}            ;Restore a load of registers
838
839                 ; --- Now move on to the next square ---
840
841                 ADD     R6,R6,R3                ;Add on the x increment
842                 CMP     R6,R11                  ;Have we gone too far?
843                 ADDLE   R5,R5,R3,LSL R0         ;No -- add on the palette val
844                 BLE     %10rgb_plotSquare       ;And go round again
845
846                 SUB     R7,R7,R4                ;Subtract the y increment
847                 CMP     R7,R12                  ;Have we gone too far?
848                 SUBGE   R5,R5,R4,LSL R1         ;No -- subtract palette val
849                 BGE     %00rgb_plotSquare       ;And do the next row nicely
850
851                 LDMFD   R13!,{R0-R12,PC}^       ;Return to caller
852
853                 ; --- Fast colour setting routines ---
854
855 20              MOV     R1,R5,LSR #8            ;Get hardware colour value
856                 MOV     R0,#0                   ;Set the colour
857                 SWI     OS_SetColour            ;Set the colour really
858                 B       %15rgb_plotSquare       ;And return to main loop
859
860 25              AND     R0,R5,#&F800            ;Get the red bits out
861                 MOV     R1,R0,LSR #11           ;Shift them down
862                 AND     R0,R5,#&F80000          ;Get the green bits
863                 ORR     R1,R1,R0,LSR #14        ;Move them in nicely
864                 AND     R0,R5,#&F8000000        ;Get the blue bits too
865                 ORR     R1,R1,R0,LSR #17        ;Move them in too
866                 MOV     R0,#0                   ;Set a raw colour
867                 SWI     OS_SetColour            ;Set the colour nicely
868                 B       %15rgb_plotSquare       ;And return to main loop
869
870 30              MOV     R14,#3                  ;Mask bits off quickly
871                 AND     R0,R14,R5,LSR #12       ;Get the red bits
872                 AND     R1,R14,R5,LSR #20       ;Get the green bits
873                 AND     R2,R14,R5,LSR #28       ;And the blue bits
874                 ADD     R1,R1,R1,LSL #2         ;Multiply green by 5
875                 ADD     R2,R2,R0,LSL #1         ;Mult red by 2 and add in
876                 ADD     R2,R2,R1                ;And add in weighted green
877                 MOV     R1,R2,LSR #3            ;Get weighted average
878
879                 AND     R0,R5,#&00C00000        ;Get top two green bits
880                 ORR     R1,R1,R0,LSR #17        ;Shift into position
881                 TST     R5,#&00004000           ;Get red bit two
882                 ORRNE   R1,R1,#&4               ;If set, set in colour
883                 TST     R5,#&40000000           ;Get blue bit two
884                 ORRNE   R1,R1,#&8               ;If set, set in colour
885                 TST     R5,#&00008000           ;Get red bit three
886                 ORRNE   R1,R1,#&10              ;If set, set in colour
887                 TST     R5,#&80000000           ;Get blue bit three
888                 ORRNE   R1,R1,#&80              ;If set, set in colour
889
890                 MOV     R0,#0                   ;Set raw colour
891                 SWI     OS_SetColour            ;Do the colour setting
892                 B       %15rgb_plotSquare       ;And return to main loop
893                 
894                 LTORG
895
896 ; --- rgb__plot32k ---
897 ;
898 ; On entry:     R0 == left side of square to plot
899 ;               R1 == bottom of square to plot
900 ;               R2 == rotation number
901 ;               R3 == x step for rectangles
902 ;               R4 == y step for rectangles
903 ;               R5 == current z-value (in 16.16)
904 ;               R6 == pointer to graphics window block
905 ;               R7 == unlimited relative max y position to plot
906 ;               R8 == pointer to screen info block
907 ;               R10 == unlimited relative min x position to plot
908 ;               R11 == unlimited relative max x position to plot
909 ;               R12 == unlimited relative min y position to plot
910 ;               On stack: saved {R0-R12,R14}
911 ;
912 ; On exit:      --
913 ;
914 ; Use:          Displays an RGB square on the screen at a given location,
915 ;               in a 16bpp mode, using direct screen access (TM).
916
917 rgb__plot32k    ROUT
918
919                 ; --- Prologue: Limit the relative box positions ---
920
921                 ADD     R8,R8,#screen_dx        ;Find the pixel positions
922                 LDMIA   R8,{R8,R9}              ;Load them into registers
923
924                 CMP     R10,#0                  ;Is min x too small?
925                 MOVLT   R10,#0                  ;Yes -- raise it to 0
926                 CMP     R12,#0                  ;Is min y too small?
927                 MOVLT   R12,#0                  ;Yes --- raise that too
928                 CMP     R11,#256                ;Is the max x too large?
929                 MOVGT   R11,#256                ;Yes -- reduce it then
930                 CMP     R7,#256                 ;Is the max y too large?
931                 MOVGT   R7,#256                 ;Yes -- reduce it then
932                 SUB     R11,R11,R8              ;Make this inclusive
933                 SUB     R7,R7,R9                ;Make this inclusive too
934
935                 ; --- Act 1: Find addresses of things on the screen ---
936
937                 ADD     R9,R0,R10               ;Work out left hand side
938                 ADD     R8,R1,R7                ;Work out top of area
939                 SUB     R10,R11,R10             ;Work out width of area
940                 SUB     R7,R7,R12               ;And the height too
941
942                 SUB     R12,R9,R0               ;Work out left offset again
943                 SUB     R11,R8,R1               ;And the top offset too
944
945                 SUB     R13,R13,#20             ;Space for our vdu vars
946                 ADR     R0,rgb__vduVars         ;Point to the var numbers
947                 MOV     R1,R13                  ;Point to our output block
948                 SWI     OS_ReadVduVariables     ;Get the values nicely
949
950                 ; --- Interlude: Set up rectangle sizes ---
951
952                 CMP     R3,#8                   ;Make sure rectangles are >8
953                 MOVCC   R3,#8                   ;If not, make them bigger
954                 MOVCC   R4,#8                   ;(Width and height the same)
955                 MOV     R14,R3,LSR #3           ;Work out colour increment
956
957                 ; --- Reprise: Convert measurements to pixels ---
958
959                 LDMIA   R13!,{R0,R1}            ;Load the x and y eig things
960                 MOV     R3,R3,LSR R0            ;Convert pixel counters
961                 MOV     R4,R4,LSR R1            ;Convert other pixel counter
962                 MOV     R9,R9,LSR R0            ;Convert left hand side
963                 MOV     R10,R10,LSR R0          ;Convert width of area
964                 MOV     R7,R7,LSR R1            ;Convert area height
965                 MOV     R8,R8,LSR R1            ;And the top position
966
967                 ; --- Intermission: Pack up pixel counters ---
968                 ;
969                 ; We pack all this into a word containing the following:
970                 ;
971                 ; bits 31-24 == x counter reset value
972                 ; bits 23-20 == y counter initial value
973                 ; bits 19-16 == x counter initial value
974                 ; bits 15- 8 == y counter reset value
975                 ; bits  7- 0 == colour step value
976                 ;
977                 ; Can anyone say `Z80 programming techniques'?
978
979                 MOV     R12,R12,LSR R0          ;Get left offset in pixels
980                 SUB     R6,R3,#1                ;Get the h pixel count -1
981                 AND     R0,R12,R6               ;Get the remainder thing
982                 SUB     R0,R3,R0                ;And get the correct offset
983
984                 ORR     R3,R4,R3,LSL #16        ;Pack x and y counters
985                 ORR     R3,R14,R3,LSL #8        ;And move in the colour inc
986
987                 RSB     R14,R11,#256            ;Get offset from top
988                 MOV     R11,R11,LSR R1          ;Turn offset into pixels
989                 MOV     R1,R14,LSR R1           ;Get top offset in pixels
990                 SUB     R1,R1,#1                ;Subtract one for niceness
991                 SUB     R6,R4,#1                ;Get the v pixel count -1
992                 AND     R1,R1,R6                ;Get the remainder thing
993                 SUB     R1,R4,R1                ;And get the correct offset
994                 ORR     R0,R0,R1,LSL #4         ;Pack into 1 byte
995
996                 ORR     R3,R3,R0,LSL #16        ;Put in initial values too
997
998                 LDMIA   R13!,{R0,R1,R6}         ;Load other vdu vars
999                 SUB     R14,R1,R8               ;Shift origin to top left
1000                 MLA     R0,R14,R6,R0            ;Work out address of row
1001                 ADD     R9,R0,R9,LSL #1         ;Work out left address
1002                 ADD     R8,R9,R10,LSL #1        ;Work out right hand side too
1003
1004                 ; --- Act 2: Set up colour information ---
1005
1006                 AND     R14,R3,#&FF             ;Get the colour step value
1007                 BIC     R10,R3,#&FF             ;Move packed init values away
1008                 
1009                 RSB     R5,R5,R5,LSL #8         ;Multiply z value by 255
1010                 MOV     R5,R5,LSR #19           ;And make it 0-31
1011
1012                 AND     R3,R10,#&FF000000       ;Get the x pixel count reinit
1013                 SUB     R3,R3,#&01000000        ;Turn it into a bitmask
1014                 BIC     R3,R12,R3,LSR #24       ;Round colour down nicely
1015                 LDR     R12,[R13,#-20]          ;Get the xeig factor
1016                 MOV     R3,R3,LSL R12           ;Shift colour up to OS units
1017                 MOV     R3,R3,LSR #3            ;Get the x colour in 0-31
1018
1019                 AND     R4,R10,#&0000FF00       ;Get the y pixel count reinit
1020                 SUB     R4,R4,#&00000100        ;Turn it into a bitmask
1021                 BIC     R4,R11,R4,LSR #8        ;Round colour down nicely
1022                 LDR     R11,[R13,#-16]          ;Get the yeig factor
1023                 MOV     R4,R4,LSL R11           ;Shift colour up to OS units
1024                 MOV     R4,R4,LSR #3            ;And the y one too please
1025
1026                 MOV     R12,#&1F                ;This is a useful value
1027
1028                 CMP     R2,#0                   ;Is this the red rotation?
1029                 MOVEQ   R0,R5,LSL #16           ;Build the colour up...
1030                 ORREQ   R0,R0,R4,LSL #21        ;Still doing that...
1031                 ORREQ   R0,R0,R3,LSL #26        ;Almost finished now...
1032                 MOVEQ   R1,R3,LSL #26           ;And the x-init value
1033                 MOVEQ   R3,R14,LSL #21          ;Get the y increment right
1034                 MOVEQ   R4,R14,LSL #26          ;And the x increment
1035                 MOVEQ   R5,R12,LSL #26          ;Get the x-clear mask
1036
1037                 CMP     R2,#1                   ;Is this the green rotation?
1038                 MOVEQ   R0,R3,LSL #16           ;Build the colour up...
1039                 ORREQ   R0,R0,R5,LSL #21        ;Still doing that...
1040                 ORREQ   R0,R0,R4,LSL #26        ;Almost finished now...
1041                 MOVEQ   R1,R3,LSL #16           ;And the x-init value
1042                 MOVEQ   R3,R14,LSL #26          ;Get the y increment right
1043                 MOVEQ   R4,R14,LSL #16          ;And the x increment
1044                 MOVEQ   R5,R12,LSL #16          ;Get the x-clear mask
1045
1046                 CMP     R2,#2                   ;Is this the blue rotation?
1047                 MOVEQ   R0,R4,LSL #16           ;Build the colour up...
1048                 ORREQ   R0,R0,R3,LSL #21        ;Still doing that...
1049                 ORREQ   R0,R0,R5,LSL #26        ;Almost finished now...
1050                 MOVEQ   R1,R3,LSL #21           ;Get the x-init value
1051                 MOVEQ   R3,R14,LSL #16          ;Get the y increment right
1052                 MOVEQ   R4,R14,LSL #21          ;And the x increment
1053                 MOVEQ   R5,R12,LSL #21          ;Get the x-clear mask
1054
1055                 ; --- Act 3. Initialise the pixel counts ---
1056
1057                 MOV     R14,#&F                 ;For reading nibbles
1058                 AND     R12,R14,R10,LSR #16     ;Get the initial x value
1059                 AND     R2,R14,R10,LSR #20      ;Get the initial y value too
1060                 ORR     R2,R10,R2               ;Put that into the count reg
1061                 SWI     OS_EnterOS              ;Avoid problems with PhysMem
1062
1063                 ; --- Act 4. Plot the bloody thing ---
1064
1065 10rgb__plot32k  MOV     R10,R9                  ;Get the current address
1066                 MOV     R11,#0                  ;Clear the buffer value
1067                 STMFD   R13!,{R12}              ;Save the x count value
1068
1069                 ; --- Start plotting this row ---
1070
1071                 TST     R10,#2                  ;Is this address aligned?
1072                 BEQ     %20rgb__plot32k         ;Yes -- start at main loop
1073                 LDR     R14,[R10,#-2]           ;No -- load word from here
1074                 MOV     R14,R14,LSL #16         ;Shift all the way up
1075                 ORR     R14,R0,R14,LSR #16      ;Build the replacement word
1076                 STR     R14,[R10,#-2]           ;And store in frame buffer
1077                 B       %25rgb__plot32k         ;Jump to end of loop
1078
1079                 ; --- Main row plotting loop (time critical :-) ) ---
1080
1081 20rgb__plot32k  ORR     R11,R0,R11,LSR #16      ;Add colour into buffer
1082                 TST     R10,#2                  ;Is this an odd address?
1083                 STRNE   R11,[R10,#-2]           ;Yes -- done both halfwords
1084
1085 25rgb__plot32k  ADD     R10,R10,#2              ;Move on to next pixel
1086                 CMP     R10,R8                  ;Have we finished yet?
1087                 BHI     %30rgb__plot32k         ;No -- do the rest then
1088                 SUBS    R12,R12,#1              ;Decrement pixel counter
1089                 ADDEQ   R0,R0,R4                ;If cleared, add on colour
1090                 MOVEQ   R12,R2,LSR #24          ;And reinitialise counter
1091                 B       %20rgb__plot32k         ;Go round for more
1092
1093                 ; --- We've finished; do we have a halfword left over? ---
1094
1095 30rgb__plot32k  TST     R10,#2                  ;Is the address odd?
1096                 LDRNE   R14,[R10,#-2]           ;Yes -- read the old word
1097                 MOVNE   R11,R11,LSR #16         ;Get buffer value in low hw
1098                 MOVNE   R14,R14,LSR #16         ;Get screen value in low hw
1099                 ORRNE   R14,R11,R14,LSL #16     ;Build correct word to write
1100                 STRNE   R14,[R10,#-2]           ;Store this word away
1101
1102                 ; --- Now move on to the next row ---
1103
1104                 LDMFD   R13!,{R12}              ;Unstack initial x counter
1105                 ADD     R9,R9,R6                ;Move start address down 1
1106                 ADD     R8,R8,R6                ;Move end address down 1
1107                 BIC     R0,R0,R5                ;Clear the x colour section
1108                 ORR     R0,R0,R1                ;Reintialise the x colour
1109                 SUB     R2,R2,#1                ;Decrement y counter
1110                 TST     R2,#&FF                 ;Is it now zero?
1111                 BICEQ   R2,R2,#&00FF0000        ;Clear unused byte in word
1112                 ORREQ   R2,R2,R2,LSR #8         ;Yes -- reinitialise
1113                 SUBEQ   R0,R0,R3                ;And increment the y colour
1114                 SUBS    R7,R7,#1                ;Decrement scan line counter
1115                 BCS     %10rgb__plot32k         ;And go back up again
1116
1117                 TEQP    PC,#0                   ;Return to user mode
1118                 MOV     R0,R0                   ;Keep ARM ecstatically happy
1119                 LDMFD   R13!,{R0-R12,PC}^       ;Return to caller
1120
1121 rgb__vduVars    DCD     4,5                     ;X and Y eigen factors
1122                 DCD     149                     ;Start of display memory
1123                 DCD     12                      ;How high is the screen
1124                 DCD     6                       ;Width of scan line in pixels
1125                 DCD     -1
1126
1127                 LTORG
1128
1129 ; --- rgb__plot16m ---
1130 ;
1131 ; On entry:     R0 == left side of square to plot
1132 ;               R1 == bottom of square to plot
1133 ;               R2 == rotation number
1134 ;               R3 == x step for rectangles
1135 ;               R4 == y step for rectangles
1136 ;               R5 == current z-value (in 16.16)
1137 ;               R6 == pointer to graphics window block
1138 ;               R7 == unlimited relative max y position to plot
1139 ;               R8 == pointer to screen info block
1140 ;               R10 == unlimited relative min x position to plot
1141 ;               R11 == unlimited relative max x position to plot
1142 ;               R12 == unlimited relative min y position to plot
1143 ;               On stack: saved {R0-R12,R14}
1144 ;
1145 ; On exit:      --
1146 ;
1147 ; Use:          Displays an RGB square on the screen at a given location,
1148 ;               in a 32bpp mode, using direct screen access (TM).
1149
1150 rgb__plot16m    ROUT
1151
1152                 ; --- Prologue: Limit the relative box positions ---
1153
1154                 ADD     R8,R8,#screen_dx        ;Find the pixel positions
1155                 LDMIA   R8,{R8,R9}              ;Load them into registers
1156
1157                 CMP     R10,#0                  ;Is min x too small?
1158                 MOVLT   R10,#0                  ;Yes -- raise it to 0
1159                 CMP     R12,#0                  ;Is min y too small?
1160                 MOVLT   R12,#0                  ;Yes --- raise that too
1161                 CMP     R11,#256                ;Is the max x too large?
1162                 MOVGT   R11,#256                ;Yes -- reduce it then
1163                 CMP     R7,#256                 ;Is the max y too large?
1164                 MOVGT   R7,#256                 ;Yes -- reduce it then
1165                 SUB     R11,R11,R8              ;Make this inclusive
1166                 SUB     R7,R7,R9                ;Make this inclusive too
1167
1168                 ; --- Act 1: Find addresses of things on the screen ---
1169
1170                 ADD     R9,R0,R10               ;Work out left hand side
1171                 ADD     R8,R1,R7                ;Work out top of area
1172                 SUB     R10,R11,R10             ;Work out width of area
1173                 SUB     R7,R7,R12               ;And the height too
1174
1175                 SUB     R12,R9,R0               ;Work out left offset again
1176                 SUB     R11,R8,R1               ;And the top offset too
1177
1178                 SUB     R13,R13,#20             ;Space for our vdu vars
1179                 ADR     R0,rgb__vduVars         ;Point to the var numbers
1180                 MOV     R1,R13                  ;Point to our output block
1181                 SWI     OS_ReadVduVariables     ;Get the values nicely
1182
1183                 ; --- Reprise: Convert measurements to pixels ---
1184
1185                 LDMIA   R13!,{R0,R1}            ;Load the x and y eig things
1186                 MOV     R3,R3,LSR R0            ;Convert pixel counters
1187                 MOV     R4,R4,LSR R1            ;Convert other pixel counter
1188                 MOV     R9,R9,LSR R0            ;Convert left hand side
1189                 MOV     R10,R10,LSR R0          ;Convert width of area
1190                 MOV     R7,R7,LSR R1            ;Convert area height
1191                 MOV     R8,R8,LSR R1            ;And the top position
1192
1193                 ; --- Intermission: Pack up pixel counters ---
1194                 ;
1195                 ; We pack all this into a word containing the following:
1196                 ;
1197                 ; bits 31-24 == x counter reset value
1198                 ; bits 23-20 == y counter initial value
1199                 ; bits 19-16 == x counter initial value
1200                 ; bits 15- 8 == y counter reset value
1201                 ; bits  7- 0 == colour step value
1202                 ;
1203                 ; Can anyone say `Z80 programming techniques'?
1204
1205                 MOV     R12,R12,LSR R0          ;Get left offset in pixels
1206                 SUB     R6,R3,#1                ;Get the h pixel count -1
1207                 AND     R0,R12,R6               ;Get the remainder thing
1208                 SUB     R0,R3,R0                ;And get the correct offset
1209
1210                 ORR     R3,R4,R3,LSL #16        ;Pack x and y counters
1211                 MOV     R3,R3,LSL #8            ;Move that up one byte
1212
1213                 RSB     R14,R11,#256            ;Get offset from top
1214                 MOV     R11,R11,LSR R1          ;Turn offset into pixels
1215                 MOV     R1,R14,LSR R1           ;Get top offset in pixels
1216                 SUB     R1,R1,#1                ;Subtract one for niceness
1217                 SUB     R6,R4,#1                ;Get the v pixel count -1
1218                 AND     R1,R1,R6                ;Get the remainder thing
1219                 SUB     R1,R4,R1                ;And get the correct offset
1220                 ORR     R0,R0,R1,LSL #4         ;Pack into 1 byte
1221
1222                 ORR     R3,R3,R0,LSL #16        ;Put in initial values too
1223
1224                 LDMIA   R13!,{R0,R1,R6}         ;Load other vdu vars
1225                 SUB     R14,R1,R8               ;Shift origin to top left
1226                 MLA     R0,R14,R6,R0            ;Work out address of row
1227                 ADD     R9,R0,R9,LSL #2         ;Work out left address
1228                 ADD     R8,R9,R10,LSL #2        ;Work out right hand side too
1229
1230                 ; --- Act 2: Set up colour information ---
1231
1232                 BIC     R10,R3,#&FF             ;Move packed init values away
1233                 
1234                 RSB     R5,R5,R5,LSL #8         ;Multiply z value by 255
1235                 MOV     R5,R5,LSR #16           ;And make it 0-255
1236
1237                 AND     R3,R10,#&FF000000       ;Get the x pixel count reinit
1238                 SUB     R3,R3,#&01000000        ;Turn it into a bitmask
1239                 BIC     R3,R12,R3,LSR #24       ;Round colour down nicely
1240                 LDR     R12,[R13,#-20]          ;Get the xeig factor
1241                 MOV     R3,R3,LSL R12           ;Shift colour up to OS units
1242                 AND     R14,R10,#&FF000000      ;Get the x reinit value
1243                 MOV     R14,R14,LSR #24         ;Bring it down to earth
1244                 MOV     R14,R14,LSL R12         ;And turn into OS units
1245
1246                 AND     R4,R10,#&0000FF00       ;Get the y pixel count reinit
1247                 SUB     R4,R4,#&00000100        ;Turn it into a bitmask
1248                 BIC     R4,R11,R4,LSR #8        ;Round colour down nicely
1249                 LDR     R12,[R13,#-16]          ;Get the yeig factor
1250                 MOV     R4,R4,LSL R12           ;Shift colour up to OS units
1251                 AND     R11,R10,#&0000FF00      ;Get the y reinit value
1252                 MOV     R11,R11,LSR #8          ;Bring it down to earth
1253                 MOV     R11,R11,LSL R12         ;And turn into OS units
1254
1255                 MOV     R12,#&FF                ;This is a useful value
1256
1257                 CMP     R2,#0                   ;Is this the red rotation?
1258                 MOVEQ   R0,R5,LSL #0            ;Build the colour up...
1259                 ORREQ   R0,R0,R4,LSL #8         ;Still doing that...
1260                 ORREQ   R0,R0,R3,LSL #16        ;Almost finished now...
1261                 MOVEQ   R1,R3,LSL #16           ;And the x-init value
1262                 MOVEQ   R3,R11,LSL #8           ;Get the y increment right
1263                 MOVEQ   R4,R14,LSL #16          ;And the x increment
1264                 MOVEQ   R5,R12,LSL #16          ;Get the x-clear mask
1265
1266                 CMP     R2,#1                   ;Is this the green rotation?
1267                 MOVEQ   R0,R3,LSL #0            ;Build the colour up...
1268                 ORREQ   R0,R0,R5,LSL #8         ;Still doing that...
1269                 ORREQ   R0,R0,R4,LSL #16        ;Almost finished now...
1270                 MOVEQ   R1,R3,LSL #0            ;And the x-init value
1271                 MOVEQ   R3,R11,LSL #16          ;Get the y increment right
1272                 MOVEQ   R4,R14,LSL #0           ;And the x increment
1273                 MOVEQ   R5,R12,LSL #0           ;Get the x-clear mask
1274
1275                 CMP     R2,#2                   ;Is this the blue rotation?
1276                 MOVEQ   R0,R4,LSL #0            ;Build the colour up...
1277                 ORREQ   R0,R0,R3,LSL #8         ;Still doing that...
1278                 ORREQ   R0,R0,R5,LSL #16        ;Almost finished now...
1279                 MOVEQ   R1,R3,LSL #8            ;Get the x-init value
1280                 MOVEQ   R3,R11,LSL #0           ;Get the y increment right
1281                 MOVEQ   R4,R14,LSL #8           ;And the x increment
1282                 MOVEQ   R5,R12,LSL #8           ;Get the x-clear mask
1283
1284                 ; --- Act 3. Initialise the pixel counts ---
1285
1286                 MOV     R14,#&F                 ;For reading nibbles
1287                 AND     R12,R14,R10,LSR #16     ;Get the initial x value
1288                 AND     R2,R14,R10,LSR #20      ;Get the initial y value too
1289                 ORR     R2,R10,R2               ;Put that into the count reg
1290
1291                 ; --- Act 4. Plot the bloody thing ---
1292
1293                 SWI     OS_EnterOS              ;Avoid problems with PhysMem    
1294
1295 10rgb__plot16m  MOV     R10,R9                  ;Get the current address
1296                 MOV     R11,R12                 ;Initialise the x counter
1297                 
1298                 ; --- Main row plotting loop (time critical :-) ) ---
1299
1300 20rgb__plot16m  STR     R0,[R10],#4             ;Store this pixel
1301
1302 25rgb__plot16m  CMP     R10,R8                  ;Have we finished yet?
1303                 BHI     %30rgb__plot16m         ;No -- do the rest then
1304                 SUBS    R11,R11,#1              ;Decrement pixel counter
1305                 ADDEQ   R0,R0,R4                ;If cleared, add on colour
1306                 MOVEQ   R11,R2,LSR #24          ;And reinitialise counter
1307                 B       %20rgb__plot16m         ;Go round for more
1308
1309                 ; --- We've finished; move on to next row ---
1310
1311 30rgb__plot16m  ADD     R9,R9,R6                ;Move start address down 1
1312                 ADD     R8,R8,R6                ;Move end address down 1
1313                 BIC     R0,R0,R5                ;Clear the x colour section
1314                 ORR     R0,R0,R1                ;Reintialise the x colour
1315                 SUB     R2,R2,#1                ;Decrement y counter
1316                 TST     R2,#&FF                 ;Is it now zero?
1317                 BICEQ   R2,R2,#&00FF0000        ;Clear unused byte in word
1318                 ORREQ   R2,R2,R2,LSR #8         ;Yes -- reinitialise
1319                 SUBEQ   R0,R0,R3                ;And increment the y colour
1320                 SUBS    R7,R7,#1                ;Decrement scan line counter
1321                 BCS     %10rgb__plot16m         ;And go back up again
1322
1323                 TEQP    PC,#0                   ;Return to user mode
1324                 MOV     R0,R0                   ;Keep ARM ecstatically happy
1325                 LDMFD   R13!,{R0-R12,PC}^       ;Return to caller
1326
1327                 LTORG
1328
1329 ; --- rgb__plotHair ---
1330 ;
1331 ; On entry:     R2 == x coordinate of cross
1332 ;               R3 == y coordinate of cross
1333 ;
1334 ; On exit:      --
1335 ;
1336 ; Use:          Plots the crosshair on an RGB colour square to mark the
1337 ;               current position nicely.
1338
1339 rgb__plotHair   ROUT
1340
1341                 STMFD   R13!,{R0-R3,R14}        ;Save some registers
1342                 MOV     R0,#4                   ;Move cursor absolute
1343                 MOV     R1,R2                   ;Get the x coordinate
1344                 SUB     R2,R3,#256              ;Move down a little bit
1345                 SWI     OS_Plot                 ;Move the cursor there
1346                 MOV     R0,#2                   ;Plot in logical inverse (!)
1347                 MOV     R1,#0                   ;No x movement please
1348                 MOV     R2,#512                 ;And plot upwards
1349                 SWI     OS_Plot                 ;Plot the vertical line
1350
1351                 MOV     R0,#0                   ;Move cursor relative
1352                 MOV     R1,#-256                ;Move back a bit
1353                 MOV     R2,#-256                ;Move down a bit
1354                 SWI     OS_Plot                 ;Move the cursor there
1355                 MOV     R0,#2                   ;Plot in logical inverse (!)
1356                 MOV     R1,#512                 ;Plot the cross beam
1357                 MOV     R2,#0                   ;No y movement please
1358                 SWI     OS_Plot                 ;Plot the horizontal line
1359
1360                 MOV     R0,#0                   ;Move cursor relative
1361                 MOV     R1,#-256                ;Move back a bit
1362                 MOV     R2,#0                   ;Move back to centre
1363                 SWI     OS_Plot                 ;Move the cursor there
1364                 MOV     R0,#146                 ;Circle relative
1365                 MOV     R1,#16                  ;Radius 16
1366                 MOV     R2,#0                   ;Don't screw up calculation
1367                 SWI     OS_Plot                 ;Plot the circle
1368
1369                 LDMFD   R13!,{R0-R3,PC}^        ;And return to caller
1370
1371                 LTORG
1372
1373 ;----- Custom dbx controls --------------------------------------------------
1374
1375 ; --- rgbSquare ---
1376
1377 rgbSquare       ROUT
1378
1379                 DCD     0,0
1380                 DCD     dbxMask_redraw + dbxMask_update + dbxMask_click
1381
1382                 CMP     R0,#dbxEvent_update     ;Is it an update event?
1383                 BEQ     %10rgbSquare            ;Yes -- handle it
1384                 CMP     R0,#dbxEvent_click      ;Is it a click event?
1385                 BEQ     %20rgbSquare            ;Yes -- handle it
1386
1387                 ; --- Deal with a redraw event ---
1388
1389                 STMFD   R13!,{R0-R6,R10,R14}    ;Save some registers
1390                 MOV     R10,R8                  ;Get dbox data in R10
1391                 STMFD   R13!,{R2,R3}            ;Save bottom left corner
1392
1393                 ; --- Sort out the resolution ---
1394
1395                 BL      cs_resolution           ;Get the current resolution
1396                 CMP     R0,#0                   ;Is it pixel-level?
1397                 BLEQ    screen_getInfo          ;Yes -- get screen info
1398                 ADDEQ   R0,R0,#screen_dx        ;Point to the pixel size
1399                 LDMEQIA R0,{R3,R4}              ;And load the values
1400                 ADRNE   R14,rgb__resTable       ;Otherwise point at the table
1401                 ADDNE   R14,R14,R0              ;Find the correct entry
1402                 LDRNEB  R3,[R14,#0]             ;Load the square size
1403                 MOVNE   R4,R3                   ;And do it in both directions
1404
1405                 ; --- Sort out the z value too ---
1406
1407                 LDR     R0,rgb__zPos            ;Get the z slider value
1408                 MOV     R0,R0,LSL #16           ;Convert to 16.16 form
1409                 ADD     R0,R0,#50               ;Make it round to nearest
1410                 BL      div10                   ;Divide it by 10
1411                 BL      div10                   ;And again -- div by 100
1412                 MOV     R5,R0                   ;This is the z coordinate
1413
1414                 ; --- Call the main plot code ---
1415
1416                 LDMFD   R13!,{R0,R1}            ;Load the bottom left corner
1417                 LDR     R2,rgb__mapping         ;Get the colour mapping
1418                 BL      rgb_plotSquare          ;Do the plotting
1419                 LDMFD   R13!,{R0-R6,R10,R14}    ;Drop through to update code
1420
1421                 ; --- Plot the crosshair as part of update ---
1422
1423 10rgbSquare     STMFD   R13!,{R0-R5,R10,R14}    ;Save some registers
1424                 MOV     R10,R8                  ;Find my workspace address
1425                 SUB     R4,R4,R2                ;Get the icon width
1426                 SUB     R5,R5,R3                ;And the height
1427                 LDR     R0,rgb__xPos            ;Load cached x position
1428                 MUL     R0,R4,R0                ;Scale it to the width
1429                 ADD     R0,R0,#50               ;Round to nearest on divide
1430                 BL      div10                   ;And divide down
1431                 BL      div10                   ;And divide down again
1432                 ADD     R2,R2,R0                ;Find the x cross position
1433                 LDR     R0,rgb__yPos            ;Load cached y position
1434                 MUL     R0,R5,R0                ;Scale it to the height
1435                 ADD     R0,R0,#50               ;Round to nearest on divide
1436                 BL      div10                   ;And divide down
1437                 BL      div10                   ;And divide down again
1438                 ADD     R3,R3,R0                ;Find the y cross position
1439                 BL      rgb__plotHair           ;Plot the crosshair nicely
1440                 LDMFD   R13!,{R0-R5,R10,PC}^    ;And return to caller
1441
1442 rgb__resTable   DCB     0,4,8,16
1443
1444                 ; --- Handle click events on the square ---
1445
1446 20rgbSquare     TST     R2,#5                   ;Is it a real button click?
1447                 MOVEQS  PC,R14                  ;No -- ignore it then
1448                 STMFD   R13!,{R0-R5,R10,R14}    ;Save some registers
1449
1450                 ; --- Start the drag operation ---
1451
1452                 MOV     R0,R10                  ;Get dialogue handle
1453                 BL      dbx_controlBBox         ;Get the bonding box nicely
1454                 BL      dbox_window             ;Get the window handle
1455                 MOV     R1,#7                   ;User drag type
1456                 SUB     R13,R13,#56             ;Make a drag box on the stack
1457                 STMIA   R13,{R0,R1}             ;Save them away nicely
1458                 ADD     R14,R13,#24             ;Point to parent box
1459                 STMIA   R14,{R2-R5}             ;Save the bounding box here
1460                 MOV     R1,R13                  ;Point to my block
1461                 SWI     Wimp_DragBox            ;Set up the drag nicely
1462                 ADD     R13,R13,#56             ;Reclaim the stack space
1463
1464                 ; --- Set up the handlers nicely ---
1465
1466                 MOV     R10,R8                  ;Point to dbox data in R10
1467                 ADR     R0,rgb__ukEvents        ;Point to unknown handler
1468                 MOV     R1,#0                   ;Don't care about R4
1469                 MOV     R2,R10                  ;Pass dbox data in R10
1470                 MOV     R3,R12                  ;Pass workspace in R12
1471                 BL      win_unknownHandler      ;Register the handler
1472                 MOVVC   R0,#2                   ;Call every TV frame
1473                 ADRVC   R1,rgb__idles           ;Point to the idle handler
1474                 BLVC    idle_handler            ;Register that too
1475                 BL      rgb__idles              ;Call idle handler now
1476                 LDMFD   R13!,{R0-R5,R10,PC}^    ;Return to caller
1477
1478                 LTORG
1479
1480 ; --- rgb__idles ---
1481 ;
1482 ; On entry:     --
1483 ;
1484 ; On exit:      --
1485 ;
1486 ; Use:          Handles idle events during a drag in the colour square.
1487
1488 rgb__idles      ROUT
1489
1490                 STMFD   R13!,{R0-R5,R10,R14}    ;Save some registers
1491                 LDR     R0,cs__modelDb          ;Get the dialogue box
1492                 MOV     R1,#rgbIcon__square     ;Get my icon handle
1493                 BL      dbx_controlBBox         ;Get my bounding box nicely
1494                 SUB     R13,R13,#20             ;Get a pointer block
1495                 MOV     R1,R13                  ;Point at it nicely
1496                 SWI     Wimp_GetPointerInfo     ;Find the pointer posn
1497                 LDMIA   R13,{R0,R1}             ;Load pointer coordinates
1498                 ADD     R13,R13,#20             ;Recover that block
1499
1500                 ; --- Work out the new cross position ---
1501
1502                 SUB     R4,R4,R2                ;Work out the icon width
1503                 SUB     R5,R5,R3                ;And the icon height
1504                 SUB     R2,R0,R2                ;Work out the x offset
1505                 SUB     R3,R1,R3                ;And the y offset
1506
1507                 ADD     R2,R2,R2,LSL #2         ;Multiply x by 5
1508                 ADD     R2,R2,R2,LSL #2         ;Multiply x by 5 (x25)
1509                 MOV     R2,R2,LSL #2            ;Multiply x by 4 (x100)
1510
1511                 ADD     R3,R3,R3,LSL #2         ;Multiply y by 5
1512                 ADD     R3,R3,R3,LSL #2         ;Multiply y by 5 (x25)
1513                 MOV     R3,R3,LSL #2            ;Multiply y by 4 (x100)
1514
1515                 MOV     R0,R2                   ;Get the x value
1516                 MOV     R1,R4                   ;And the icon width
1517                 BL      div_round               ;Divide to get percentage
1518                 STR     R0,rgb__sl1Val          ;Save the x position
1519
1520                 MOV     R0,R3                   ;Get the y value
1521                 MOV     R1,R5                   ;And the icon height
1522                 BL      div_round               ;Divide to get percentage
1523                 STR     R0,rgb__sl2Val          ;Save the y position
1524
1525                 BL      rgb__xyUpdate           ;Redraw crosshairs if reqd
1526                 LDR     R0,cs__modelDb          ;Get the dialogue handle
1527                 MOV     R1,#rgbIcon__slide1     ;Get slider 1's number
1528                 BL      dbx_update              ;Redraw it quickly
1529                 MOV     R1,#rgbIcon__slide2     ;Get slider 2's number
1530                 BL      dbx_update              ;Redraw it quickly
1531                 BL      rgb__colUpdate          ;Redraw the colour button
1532
1533                 ; --- Now update the correct icons ---
1534
1535                 ADRL    R5,rgb__writeTbl+2      ;Point to icon number table
1536                 LDR     R14,rgb__mapping        ;And get the current mappiing
1537                 ADD     R5,R5,R14               ;Find the correct entry
1538
1539                 LDRB    R1,[R5,#0]              ;Load the x icon
1540                 LDR     R2,rgb__sl1Val          ;Get the new x value
1541                 BL      numWrite_set            ;Put it in the icon
1542                 LDRB    R1,[R5,#-1]             ;Load the y icon
1543                 LDR     R2,rgb__sl2Val          ;Get the new y value
1544                 BL      numWrite_set            ;Put it in the icon
1545                 LDMFD   R13!,{R0-R5,R10,PC}^    ;And return to caller
1546
1547                 LTORG
1548
1549 ; --- rgb__ukEvents ---
1550 ;
1551 ; On entry:     R0 == event code
1552 ;
1553 ; On exit:      CS if handled
1554 ;
1555 ; Use:          Handles unknown events during a drag in the RGB colour
1556 ;               square.
1557
1558 rgb__ukEvents   ROUT
1559
1560                 CMP     R0,#7                   ;Is it a drag over event?
1561                 MOVNES  PC,R14                  ;No -- then return to caller
1562                 STMFD   R13!,{R0-R3,R14}        ;Save some registers
1563                 BL      rgb__idles              ;Get one last drag position
1564                 ADR     R0,rgb__ukEvents        ;Point to unknown handler
1565                 MOV     R1,#0                   ;Don't care about R4
1566                 MOV     R2,R10                  ;Pass dbox data in R10
1567                 MOV     R3,R12                  ;Pass workspace in R12
1568                 BL      win_removeUnknownHandler ;Deregister the handler
1569                 MOVVC   R0,#2                   ;Call every TV frame
1570                 ADRVC   R1,rgb__idles           ;Point to the idle handler
1571                 BLVC    idle_removeHandler      ;Deregister that too
1572                 LDMFD   R13!,{R0-R3,PC}^        ;And return to caller
1573
1574                 LTORG
1575
1576 ;----- Icon numbers ---------------------------------------------------------
1577
1578 rgbIcon__square EQU     0                       ;The main colour square
1579 rgbIcon__slide1 EQU     1                       ;The x slider (slider 1)
1580 rgbIcon__slide2 EQU     2                       ;The y slider (slider 2)
1581 rgbIcon__slide3 EQU     3                       ;The z slider (slider 3)
1582
1583 rgbIcon__radioR EQU     4                       ;The `Red' radio button
1584 rgbIcon__writeR EQU     5                       ;The `Red' writable area
1585 rgbIcon__upR    EQU     6                       ;The `Red' up arrow button
1586 rgbIcon__downR  EQU     7                       ;The `Red' down arrow button
1587
1588 rgbIcon__radioG EQU     9                       ;The `Green' radio button
1589 rgbIcon__writeG EQU     10                      ;The `Green' writable area
1590 rgbIcon__upG    EQU     11                      ;The `Green' up arrow button
1591 rgbIcon__downG  EQU     12                      ;The `Green' down arrow buttn
1592
1593 rgbIcon__radioB EQU     14                      ;The `Blue' radio button
1594 rgbIcon__writeB EQU     15                      ;The `Blue' writable area
1595 rgbIcon__upB    EQU     16                      ;The `Blue' up arrow button
1596 rgbIcon__downB  EQU     17                      ;The `Blue' down arrow button
1597
1598 rgbIcon__wCols  EQU     20                      ;Base of the WIMP colours
1599
1600 ;----- That's all, folks ----------------------------------------------------
1601
1602                 END