It is essential that ColourTrans_Set/ReadPalette call PaletteV when they want to set the palette, to enable 'foreign' graphics hardware to function correctly.
The entry and exit conditions for the Palette vector are:
PaletteV (read)
In R0 = logical colour R1 = type of colour (16,17,18,24,25) R4 = 1 => read palette Out R2 = 1st flash colour (&BBGGRRxx) - device colour R3 = 2nd flash colour (&BBGGRRxx) - device colour R4 = 0 => operation complete
PaletteV (set)
In R0 = logical colour R1 = type of colour (16,17,18,24,25) R2 = 1st flash colour (&BBGGRRxx) - device colour R3 = 2nd flash colour (&BBGGRRxx) - device colour R4 = 2 => set palette Out R4 = 0 => operation complete
So the normal owner of the vector deliberately corrupts R4 to notify the caller that the operation was completed. Then, if we are on RISC OS 2.00, where there is no default owner, we must carry on to make the normal OS call to set/read the palette if R4<>0 on exit:
; In R0 = logical colour
; R1 = type of colour (16,17,18,24,25); Out R2 = 1st flash colour (&BBGGRRxx) - device colour
; R3 = 2nd flash colour (&BBGGRRxx) - device colour ; VC => flags preserved, VS => R0->error, flags corrupt ; (mustn't be called with V set)
readpalette Entry "R4,R9"
MOV R4,#1 ; read palette MOV R9,#PaletteV SWI XOS_CallAVector ; returns &BBGGRRxx EXIT VS
TEQ R4,#0 EXIT EQ
SWI XOS_ReadPalette ; returns &B0G0R0xx
LDRVC R4,=&F0F0F000 ; clears low nibbles and bottom byte ; (we want to preserve bits 0..7) ANDVC R14,R2,R4 ORRVC R2,R2,R14,LSR #4 ; force to &BBGGRRxx
ANDVC R14,R3,R4 ORRVC R3,R3,R14,LSR #4 ; force to &BBGGRRxx
EXITS VC EXIT LTORG
Note that if the vector is claimed, the resulting colours must be 24-bit, rather than the brain-damaged versions returned by OS_ReadPalette.
; In R0 = logical colour
; R1 = type of colour (16,17,18,24,25) ; R2 = 1st flash colour (&BBGGRRxx) - device colour ; R3 = 2nd flash colour (&BBGGRRxx) - device colour; Out VC => flags preserved, VS => R0->error, flags corrupt
; (mustn't be called with V set);
; It is in fact impossible to get R1=24or25,R2<>R3 to work.
setpalette "R4,R9"
MOV R4,#2 ; set palette MOV R9,#PaletteV SWI XOS_CallAVector EXIT VS
TEQ R4,#0 EXITS EQ
AND R14,R0,#&FF AND R4,R1,#&FF ORR R4,R14,R4,LSL #8 BIC R14,R2,#&FF ; R14 = &BBGGRR00 ORR R4,R4,R14,LSL #8 ; R4 = &GGRRr1r0 (green,red,R1,R0) MOV R14,R2,LSR #24 ; R14 = &000000BB (blue) Push "R0,R1,R4,R14" ADD R1,sp,#2*4 ; R1 -> block MOV R0,#12 ; write palette SWI XOS_Word STRVS R0,[sp] Pull "R0,R1,R4,R14"
EXITS VC EXIT
Note that when setting the palette, there is no need to alter the parameters when calling VDU 19 or OS_Word 12, since these only look at the top nibbles of each gun.
However, 24-bit palette values can only be received through the vector, since the VDU 19 and OS_Word calls cannot trust the values of the bottom nibbles of the palette values passed to them, and must treat them as being copies of the corresponding top nibbles.
Note that for back-compatibility reasons:
Even if future versions of the MOS indirected OS_ReadPalette, VDU 19 and OS_Word 12 via the palette vector:
To ensure compatibility with RISC OS 2.00, applications will have to go through the procedure mentioned above, of calling the vector first, and then trying the MOS routines.
Applications calling OS_ReadPalette can only trust the higher nibbles of the palette values, since early versions returned &B0G0R0xx, rather than &BBGGRRxx.
VDU 19 and OS_Word 15 can only trust the higher nibbles of the palette values, since we have encouraged applications to only set up the higher nibbles of the palette values. For this reason these calls will have to treat the lower nibbles of the entry parameters as being copies of the top nibbles.
Note that at the point when PaletteV is called, palette values MUST be 24-bit, so VDU 19 and OS_Word would have to munge the palette values before calling the vector, and OS_ReadPalette would have to degrade the palette values after calling the vector (ie. it should clear the bottom nibbles, to ensure compatibility with old applications). The MOS's default vector owner would also have to treat palette values as 24-bit (ie. the palette values are returned as &BBGGRRxx).
The advantage of getting the MOS functions to indirect via the vector would be to allow 'old' software to work with new graphics cards. It is likely that such software would fail to work correctly in any case.