
Title: PaletteV
Authors: Neil Raine, David De Vorchik
History:
        08-Mar-91 DDV/NDR Created.
        08-Mar-91 NDR Added section on MOS usage.
        12-Nov-91 TMD Changed spec for set palette (only needs one RGB colour).
                      Still needs to be updated to include supremacy/external bits.
                      See also Kernel.Doc.PaletteV.


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 = &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 = &BBGGRRxx - device colour
; Out   VC => flags preserved, VS => R0->error, flags corrupt
;       (mustn't be called with V set)
;

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.


