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.