Sunday, July 22, 2018

A Better VIC

The 6567 "VIC II" chip in the Commodore 64 has two memory interfaces.  One has 14 address bits and 8 data bits, and is connected to system RAM.  It does a fetch of bitmap data in the first half of every cycle, and a fetch of character pointers (or colours in bitmap mode) in the second half of the cycle during DMA (usually every 8 lines).

The other interface has 10 address bits, shared with the first interface, and 4 data bits.  It is connected to the 1Kx4 colour RAM.  Both interfaces fetch data at the same times, but only the DMA data from the colour RAM is used.

If the 6567 had a few extra pins, and RAM hadn't been so expensive at the time, colour RAM could have been extended to 16Kx8.  It would need new register similar to $D018 to control the high bits of its address.  Then we can map the bitmap and DMA data to different parts of colour RAM, and use both.

For compatibility we will need another mode bit in one of the control registers, that will force bitmap reads of colour RAM to 0.  As always, we want everything to behave the same as a standard Commodore 64 if the extra bits are 0.

This gives us twice as many bits per pixel, and an extra 4 bit colour per character cell.

Standard resolution now has two bits per pixel.  The low bit comes from system RAM, the high bit from colour RAM.  Colours could be allocated as follows:

  • 00: Low 4 bits of $D021
  • 01: Low 4 bits of colour RAM DMA data
  • 10: High 4 bits of $D021
  • 11: High 4 bits of colour RAM DMA data
This is not the final allocation - there's a big change coming soon!

In multicolour mode, we now have four bits per double-width pixel.  The low two come from system RAM, the high two from colour RAM.  We could assign each of the 16 values a different colour source (two from colour RAM, and the rest from global colour registers like $D021), but in a system with only 16 colours in total that doesn't feel like a good fit.

Instead, we assign the first 10 values to various colours, and the remaining 6 to pairs of colours.  Each pixel can then choose a different colour for its left and right halves:
  • 1010 Left = $D021  Right = colour low
  • 1011 Left = $D021  Right = colour high
  • 1100 Left = colour low  Right = $D021
  • 1101 Left = colour high  Right = $D021
  • 1110 Left = colour low  Right = colour high
  • 1111 Left = colour high  Right = colour low
That gives us the best of both modes.  We have a choice of 10 colours for double-width pixels, with 3 colours for high resolution detail, all in the same graphics mode.

Similar things can be done with bitmap graphics and sprites.

But wait...

In the C640, every byte contains 16 bits.  That doubles the amount of data available again.  For the DMA data, that's easy to use.  We can extend character pointers to allow more than 256 characters, and add flags to mirror characters horizontally or vertically.  And we can have 5 bit values in colour RAM, giving a 32 colour palette, and have three available in each character cell.

But what can we do with the extra bitmap data?  Here's a clue

No comments:

Post a Comment