Due to constraints of what can be done with the hardware I'm planning to use, my display is pretty much required to be either 640x480 or 720x576 (or 320x240/360x288, the latter formats produced by doubling pixels). But what format should I store the pixels in in memory?
Historically, there have been a lot of options:
- Monochrome text, each byte containing a character code that is used to look up pixels in a font table.
- Colour text, alternating between character codes and colours (typically 16 background and 16 foreground colours)
- Either mono or colour text with predefined graphical tiles (e.g. Commodore PET)
- Mono or colour text with ability to redefined characters to new shapes (e.g. systems based on the TMS9918 display processor or its successors, such as the TI-99/4A or MSX).
- Monochrome bitmap
- Monochrome bitmap with colours applied to areas (e.g. the 8x8 character grid of the ZX Spectrum or C64 "HiRes" mode, or 8x1 grid achieved in some non-standard C64 modes)
- 4-colour bitmap (typically with ability to select the palette, e.g. IBM PC CGA, CPC 464 Mode 1) although sometimes fixed (BBC Micro Mode 2)
- 16-colour bitmap (most micros that support multiple modes, but frequently only at low resolution, e.g. 160 horizontal pixels)
- 256-colour bitmap (e.g. VGA; this is probably not realistically achievable for an 8-bit system, other than at very low resolution)
I was originally thinking of allowing modes up to 16-colours, but the memory bandwidth requirements for that are quite high (to process 320 pixels would require 160 bytes to be read for each line; a VGA scan line last 32us, or 64us if we can use a buffer to produce a single line and output it twice). I'd still like to support it, but suspect it may only really be useful for showing small areas (perhaps as a format for sprites, or for small inset areas of the display). But that's OK -- my plan for the display hardware supports using different formats for different parts of the screen (inspired by Atari's ANTIC, but improving on it so that we can partition sections horizontally as well as vertically).
But: is there a stopgap between pure 4-colour and 16-colour that could be useful to support? 8-colour is interesting, but 3 bits per pixel makes it hard to work with -- the hardware would need to handle 8 different variations of where to pull pixels out, and only multiples of 8 pixel widths work without wasting memory. Planar arrangements are possible, but require the hardware to fetch memory from much more random locations, which is less efficient.
But there other possibilities. What about, for example, using a 2-byte record with a selection of palette entries combined with a very small bitmap using those palette entries? Something like this:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |COLOUR 0|COLOUR 1|C2 HI|PIX 4|PIX 3|PIX 2|PIX 1| +--------+--------+-----+-----+-----+-----+-----+
This arrangement has a few interesting optimizations:
- "COLOUR 0" and "COLOUR 1" are 3-bit indices into the current global palette, but "C2 HI" only provides 2 bits ... the third bit will come from elsewhere (see later)
- Because we're free to pick any colour set we want for this small group of pixels, and can easily swap the indices around with little effort, we can have one pixel that is always a particular colour - say colour 0 - and just switch to using different encoding if that pixel needs to change to another colour. So we only encode 4 pixels here, but produce 5.
- There are three colours defined, but 2 bits for each pixel... the encodings are:
00 - colour 0
01 - colour 1
10 - {c2 hi, 0}
11 - {c2 hi, 1}
We therefore get to select from 4 colours, with the constraint that two must be adjacent in the global palette.
The fact that one of the pixels is implicitly coloured makes it difficult (but not impossible) to update this on-the-fly, but that's OK -- I envisage this mostly being used for static images (e.g. backgrounds, or even sprites) with dynamically generated content using another format... perhaps this one:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |COLOUR 0|COLOUR 1|P9|P8|P7|P6|P5|P4|P3|P2|P1|P0| +--------+--------+--+--+--+--+--+--+--+--+--+--+
Here we have two pallet selections applying in the obvious fashion to 10 pixels, which makes updating the pixels quite simple, and allows a reasonable amount of flexibility.
What other formats could be useful? I'd love to hear any suggestions.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.
Hi Julian,
Currently I also am working on ideas for a video unit. The aim is to connect it to the https://hackaday.io/project/161251-1-square-inch-ttl-cpu. The goal may be partly the same as yours:
- minimal number of components
- Quarter VGA 320x240 graphic resolution (80 nS pixel time). With 55nS RAM, this should be possible. each line is repeated two times, with 8 bits per pixel, need less than 128kByte memory.
- Text mode 640x480, so at least 80 characters per line
- No specific character ROM or palette memory
- Free mixing of graphics and text mode.
My design has following system:
- Every 80nS, one byte is delivered to the video system. Each line info is repeated two times.
- If bit 7=0, this is a control byte. Bit 6 in the control byte determines if following bytes with bit7=1 are either:
- A 7-bit colorbyte, or
- A 7-bit text byte.
For graphics mode, after selecting color mode, the color pixels simply follow.
Text bytes are send to a shift register, that shifts with double frequency (40 nS). This gives double horizontal resolution for text. The text bits switch the output between selected color or a "fixed" textcolor. So a byte represents a single line of character pixels.
Problem is, that the next line has the same information bytes, but the text must be different. Solution is, to alternate text bytes for odd and even lines. This will have the result that the alignment differs by 80nS between two lines. Therefore, the 5 character bits will be alternated between left and right alignment within the 7 available text bits, as follows:
- - x x x x x odd line
x x x x x - - even line
Nice thing is, that text mode integrates good with graphics mode.
The control byte will also have some other bits:
- H and V synchronization
- Linecounter reset
- the (previously "fixed") text color (3 bits seem enough)
What do you think ?
best regards,
Roelh
Are you sure? yes | no