Hey everybody, long time 6502 fan and of course like everyone else have grand plans for my own systems (which will probably end up being 65816 based) but have given much thought to video over the years, so this thread piqued my interest. I wish there were more options for adding video to DIY builds!
AmyWorrall wrote:
Oh wow, I am surprised it lines up so exactly!
I see it as the video modes being a function of what the architecture would allow, rather than trying to achieve some arbitrary video mode and then making it work with the hardware available. Although some neat tricks were done to squeeze a little more oomph out of it...
My knowledge is mostly in regard to the C64 so my examples will be specific to that machine. It's what I had as a kid and learned to code on. Of course at the time I wished for more sprites, higher resolution, more colors, etc without thinking about exactly how that would be accomplished!
You are right that higher clock speed would allow for higher resolution/colors/etc, but keep in mind that comes with higher memory usage. The resolution and color depth of these machines at the time were both constrained both by the clock speed and the feasible amount of memory in the system at the time. For example a 320x200x8 bit (256 color) framebuffer would be 64K of RAM! RAM is cheap now of course but the address bus size is still a constraint.
Quote:
For my dream system, though, I'm still clinging to the idea of shared RAM. I just like it conceptually! My next thought experiment is going to be working out what it would take to do things like hardware sprites using the shared RAM model. I'm guessing we'd need to clock the video stuff even faster, and have some registers to keep hold of whatever video data needs to be output while the RAM access is being used to fetch sprite data for the next line.
For building an inexpensive system, shared RAM with video was the way to go on all these home micros. The drawback that always frustrated me, is that the entire system was constrained by the video system - which means that the clock speed of the main bus is set in stone, and made accelerating the CPU complicated. An accelerator card needed to have a completely separate CPU/RAM and shadow copy all writes to the main RAM. For this reason it was always my dream to build a system with dedicated video memory and decouple the two!
Anyway, since you mentioned sprites, I thought I'd summarize how the C64 VIC-II chip managed pulling extra information needed.
Similar to the specs above, at 1MHz this translates to one byte per 8 pixels at 320x200. So for each scan line, in the viewable area the VIC-II needs to grab one byte per clock cycle, and write out the corresponding 8 pixels to the screen with the 8 MHz "dot clock". By alternating access with the CPU on separate phases of the clock, each can access memory at an effective 2MHz combined bandwidth.
There is a problem though - for text mode, the VIC would need to read a byte for the character in that location, and then read the data from the character generator ROM. Even worse, it needs yet another byte (well, just a nibble) for color information. Graphics mode is similar in that while the bitmapped graphics are read from memory, the character matrix is used for color information in addition to the color matrix (for multicolor). So the VIC needs some way to effectively obtain three bytes of data for each clock cycle, but since two of those are shared for each 8x8 cell they can be cached and used on subsequent lines. And then there are sprites on top of all that.
On the first scan line of each 8x8 cell row, the VIC chip needs the entire bus, or 2 MHz of bandwidth. It shuts down the CPU for this scan line and during each cycle it does two memory accesses - one to the character matrix (which does double duty as character code, or partial color info for graphics mode), and one for the bit map data. Where does the extra access for the color matrix come from? There is a 1k x 4 bit static RAM chip in the C64 that holds color information for all cells, and the VIC chip has a private 4-bit data bus to this chip. When it reads the character matrix, it simultaneously reads from color RAM. Since the character matrix has to be located on a 1K boundary, the low order address bits can be shared with the color RAM chip.
The extra information is cached in the VIC chip to be used for the next 7 lines, and the cycle starts over again. Each line where the CPU is stopped is referred to as a "bad line".
Sprite data is read and cached while the border is drawn, before the next scan line starts. Since it is read and refreshed every scan line, sprites can be multiplexed. And if you count the cycles available, it works out to be just enough for the C64's 8 sprites, each three bytes (24 pixels) wide.
The result is 16 colors on the screen simultaneously (up to 4 per 8x8 cell), and 8 sprites with up to 3 colors each using 8kB for the graphics, and 1.5kB for color info. Since there is no extra bandwidth, multicolor mode reduces the resolution to 160x200 to use two bits per pixel.
With just a little extra headroom, this could be greatly simplified with a higher clock speed and more bits per pixel. The tiled graphics mode though is a force multiplier for scrolling (using character mode with a custom character set, much like the NES and other game hardware) combined with a hardware scroll function of 8 pixels. Otherwise the 1MHz CPU wasn't fast enough to scroll a graphics screen. It can barely scroll a character screen flicker free. And the color RAM isn't relocatable, so while you can build a new buffer for the screen character matrix and then switch the buffer every 8 pixels, you have to update the color RAM in place. This means starting the update right after the raster starts (chasing the raster) which gets you half way by the time the screen is rendered, and then finishing the bottom half before the raster catches up on the subsequent screen refresh.