Subject: Frame-buffer consoles -- discussion
To: None <tech-kern@netbsd.org>
From: Ben Harris <bjh21@netbsd.org>
List: tech-kern
Date: 08/17/2002 19:23:36
I'm trying to make the sys/dev/rasops code work in all bit-depths on
acorn26.  This has led me to reaslise that the code makes several unstated
assumptions about how frame buffers work, many of which are likely not to
be valid of all frame buffers.  In particular, I think its view of byte-
and bit-order is excessively simplistic.  My intention here is to record
what I think rasops should be able to rely on about a frame buffer, and
hence what parameters it needs to allow for.  Comments are very welcome.

1: All frame buffers are linearly mapped, and behave like other memory.
In particular, if you write a word and read it back as bytes, you'll get
the same result as in main memory.  Thus we can treat the frame buffer as
a sequence of bytes without loss of generality.

2: A pixel value is conceptually represented by an /n/-bit word, where /n/
is the depth of the frame buffer.

3: A little-endian frame buffer on a little-endian host takes the bytes of
the frame buffer and handles them according to the current bit-depth:
	depth <= 8: Split the byte into /n/-bit chunks.  Each chunk
		represents a pixel, with the least significant chunk
		representing the leftmost pixel.
	depth > 8: Join bytes together to form pixels (two bytes for 15
		or 16 bpp, three for 24 bpp, four for 32 bpp).  The first
		byte in memory represents the least significant eight bits
		of the pixel.  If this produces too many bits (e.g. in 15
		bpp), the spare high-order bit(s) are discarded.

4: A big-endian frame buffer on a big endian host is like a little-endian
frame buffer on a little-endian host, but with "least significant"
replaced by "most significant".

5: A little-endian frame buffer on a big-endian host reads /m/ bytes at a
time, byte-swaps them, then treats the bytes as if it was on a
little-endian host.

6: A big-endian frame buffer on a little-endian host reads /m/ bytes at a
time, byte-swaps them, then treats the bytes as if it was on a big-endian
host.

So we seem to have four parameters to describe the pixel format:

bpp: The current bit depth
host_endian: The byte-order of the host CPU
fb_endian: The byte-order of the frame buffer
fb_wordsize: The value of /m/ when host_endian != fb_endian

I think the current rasops code implements these as follows (but the code
isn't the easiest to follow, and my brain is turning to mush in the heat):

         host_endian  fb_endian  fb_wordsize data
rasops1           BE      BE         -       0b01234567
rasops1           LE      BE         1       0b01234567
rasops2           BE      BE         -       0b00112233
rasops2           LE      BE         1       0b00112233
rasops4           BE      **         **      0x2301
rasops4           LE      BE         1       0x2301
rasops8           BE      BE         -       0x00112233
rasops8           LE      LE         -       0x33221100
rasops8+RI_BSWAP  BE      LE         4       0x33221100
rasops8+RI_BSWAP  LE      BE         4       0x00112233
rasops15          BE      **         **      0x3a3b2a2b 0x1a1b0a0b
rasops15          LE      LE         -       0x1a1b0a0b 0x3a3b2a2b
rasops15+RI_BSWAP BE      LE         8       0x3b3a2b2a 0x1b1a0b0a
rasops15+RI_BSWAP LE      **         **      0x1b1a0b0a 0x3b3a2b2a
rasops24          BE      **         **      0x2a2b2c3a 0x3b3c1a1b 0x1c0a0b0c
rasops24          LE      **         **      0x1a0c0b0a 0x2b2a1c1b 0x3c3b3a2c
rasops24+RI_BSWAP BE      **         **      0x3a2c2b2a 0x1b1a3c3b 0x0c0b0a1c
rasops24+RI_BSWAP LE      BE         4       0x0a0b0c1a 0x1b1c2a2b 0x2c3a3b3c
rasops32          BE      BE         -       0x0a0b0c0d
rasops32          LE      LE         -       0x0a0b0c0d
rasops32+RI_BSWAP BE      LE         4       0x0d0c0b0a
rasops32+RI_BSWAP LE      BE         4       0x0d0c0b0a

"data" shows what the code writes to the frame buffer, given pixels of:

rasops1   0b0, 0b1, 0b2, 0b3, 0b4, 0b6, 0b7
rasops2   0b00, 0b11, 0b22, 0b33
rasops4   0x0, 0x1, 0x2, 0x3
rasops8   0x00, 0x11, 0x22, 0x33
rasops15  0x0a0b, 0x1a1b, 0x2a2b, 0x3a3b
rasops24  0x0a0b0c, 0x1a1b1c, 0x2a2b2c, 0x3a3b3c
rasops32  0x0a0b0c0d

I'd really like to know (a) if any of the alleged facts above are wrong,
and (b) if any of the modes marked ** in the table above are actually
being used.

-- 
Ben Harris                                                   <bjh21@netbsd.org>
Portmaster, NetBSD/acorn26           <URL:http://www.netbsd.org/Ports/acorn26/>