<?xml version="1.0"?>
<!DOCTYPE riscos-prm PUBLIC "-//Gerph//DTD PRM documentation 1.03//EN"
                            "http://gerph.org/dtd/103/prm.dtd">

<riscos-prm>
<chapter title="InverseTable">

<section title="Introduction and Overview">
<p>
The InverseTable module provides a fast mapping between 8bpp palette entries and
reduced 5:5:5 RGB colour values. It is intended for clients that need to convert
colours repeatedly when rendering or compositing paletted graphics.
</p>

<p>
The module supplies two SWIs. <reference type="swi" name="InverseTable_Calculate" />
returns tables for the current screen mode, and
<reference type="swi" name="InverseTable_SpriteTable" /> returns equivalent tables
for a sprite palette. Both interfaces are only valid for 8bpp palettes.
</p>

<p>
These tables are commonly used by modules which need to blend, remap, or quantise
paletted colours without performing a full nearest-colour search for every pixel.
</p>
</section>

<section title="Technical Details">
<p>
InverseTable exposes two related tables:
</p>

<p>
<list type="unordered">
 <item><p>An index-to-5:5:5 table, addressed by palette index and returning a
  32-bit word containing a packed 5:5:5 RGB value.</p></item>
 <item><p>A 5:5:5-to-index table, addressed by a packed 5:5:5 RGB value and
  returning the nearest palette index as a byte.</p></item>
</list>
</p>

<category title="5:5:5 RGB format">
<p>
The packed RGB values use 15 significant bits, arranged as:
</p>

<p>
<extended-example type="format">
bit 14..10  Blue
bit  9.. 5  Green
bit  4.. 0  Red
</extended-example>
</p>

<p>
The value returned by the index-to-5:5:5 table can be used directly as an index
into the 5:5:5-to-index table.
</p>
</category>

<category title="Mode restrictions">
<p>
Both SWIs require a palette with 256 entries. Calls made for non-8bpp screen
modes or sprite palettes report the standard <systemoutput>Bad MODE</systemoutput>
error.
</p>
</category>

<category title="Caching">
<p>
The module may return pointers to cached tables rather than rebuilding them on
every call. Clients must therefore treat the returned memory as module-owned and
read-only.
</p>
</category>
</section>

<section title="SWI Calls">

<swi-definition name="InverseTable_Calculate"
                number="4BF40"
                description="Return inverse colour tables for the current 8bpp screen palette"
                irqs="undefined"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
 <register-use number="0-9" state="preserved" />
</entry>

<exit>
 <register-use number="0">Pointer to the index-to-5:5:5 RGB table</register-use>
 <register-use number="1">Pointer to the 5:5:5 RGB-to-index table</register-use>
</exit>

<use>
<p>
This SWI returns pointers to the tables for the current screen palette. If the
cached tables are invalid, they are recomputed before the pointers are returned.
</p>

<p>
The index-to-5:5:5 RGB table contains 256 words. The 5:5:5 RGB-to-index table
contains 32768 bytes, one for each possible 15-bit RGB value.
</p>

<p>
This SWI is only valid when the current screen mode is 8bpp. In other modes the
call reports <systemoutput>Bad MODE</systemoutput>. If the SWI reports an error,
R1 is not preserved.
</p>
</use>

<related>
 <reference type="swi" name="InverseTable_SpriteTable" />
</related>

</swi-definition>


<swi-definition name="InverseTable_SpriteTable"
                number="4BF41"
                description="Return inverse colour tables for a sprite palette"
                irqs="undefined"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
 <register-use number="0">Pointer to a caller-supplied index-to-5:5:5 table buffer, or 0</register-use>
 <register-use number="1">Pointer to a caller-supplied 5:5:5-to-index table buffer, or 0</register-use>
 <register-use number="2">Sprite area, as for R0 of <reference type="swi" name="ColourTrans_ReadPalette" /></register-use>
 <register-use number="3">Sprite pointer, as for R1 of <reference type="swi" name="ColourTrans_ReadPalette" /></register-use>
</entry>

<exit>
 <register-use number="0">Pointer to the index-to-5:5:5 table. This may differ from the value supplied on entry if a cached table is returned.</register-use>
 <register-use number="1">Pointer to the 5:5:5-to-index table. This may differ from the value supplied on entry if a cached table is returned.</register-use>
</exit>

<use>
<p>
This SWI returns tables for a particular sprite palette instead of the current
screen palette. The sprite and sprite area are interpreted using the same
conventions as the palette-reading interfaces.
</p>

<p>
If cached tables already exist for the requested palette, the module may return
those cached pointers instead of using the caller's supplied buffers.
</p>

<p>
As with <reference type="swi" name="InverseTable_Calculate" />, this SWI is only
valid for 8bpp palettes.
</p>
</use>

<related>
 <reference type="swi" name="InverseTable_Calculate" />
</related>

</swi-definition>

</section>

<section title="Examples">
<p>
The following BASIC example obtains the tables for the current 8bpp screen mode:
</p>

<p>
<extended-example type="basic">
MODE 28
SYS "InverseTable_Calculate" TO to555%, from555%
PRINT "Index 0 maps to &amp;"; ~to555%!0
PRINT "Nearest index for 5:5:5 value 0 is "; ?from555%
</extended-example>
</p>

<p>
The returned word from <userinput>to555%</userinput> may be used directly as an
index into the byte table at <userinput>from555%</userinput>.
</p>
</section>

</chapter>

<meta>
 <maintainer>
  <email name="Charles Ferguson" address="gerph@gerph.org" />
 </maintainer>
 <disclaimer>
  <p>Whilst every attempt has been made to ensure the accuracy of this documentation, there may be mistakes.</p>
 </disclaimer>

 <history>
  <revision number="1.00" author="Charles Ferguson" date="18 May 2026" title="Initial documentation">
    <change>Created PRM-in-XML documentation for the InverseTable module and its two SWIs.</change>
  </revision>
 </history>
</meta>

</riscos-prm>
