ColourTrans and the Palette vector

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)
;
; NB: Doesn't cope with R1=16,R2<>R3 (write different flash states).
;     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.

The MOS and the Palette vector

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.