Because of the division of work between the CRTC and the Video ULA, I imagine any hardware sprite type facility being rather more basic than the sort of thing offered by the C64, NES or Sega Master System. Because the CRTC is basically an address generator which feeds bytes to the ULA, I find it hard to imagine how we could use it to overlay sprites of different palettes, at non-byte aligned offsets, or horizontally/vertically flipped without it needing to have some understanding of the pixel format represented by the data, which is entirely the ULA's work. But I think it could still do some useful stuff.
My tentative feature list would be as follows:
- Plot sprites at any horizontal byte position, and at any vertical pixel line (the CRTC design makes character rows the more obvious option, but I think this can be worked around).
- No fixed size for sprites: they can be any width or height, but the only limitation would be that each screen row would have a maximum number of bytes of sprite data (more later).
- Ability to set a horizontal stride for each sprite, to allow clipping off the screen edge.
- Some way to describe how screen data and sprite data are combined.
Sprites would be positioned by specifying a CRTC address (i.e. character block aligned) and a "scanline adjust" which would offset the sprite by that amount within a row, in order to provide fine vertical positioning. Offsetting the sprite across character rows would be tricky, but this kind of feature seems like the only way to work around the CRTC's chunky addressing - haven't really quite figured how this might work, nor how it could be used to clip off the top/bottom of the screen. You would be able to specify a horizontal and vertical size (in character blocks) and also a horizontal stride which needn't be the same as the horizontal size, so you could plot clipped sprites at the left and right edges.
The hardware would need to cache sprite data from RAM in advance - given that there are cycles in the horizontal border where screen memory is fetched and not used, this could be used instead to fill internal registers with sprite data for the upcoming scanline. In MODEs 0-2, there'd be a maximum of 48 cycles to do this (128 characters minus 80 displayed), hence that could be the maximum number of sprite bytes per row. That's the same as the C64 I think (8 sprites x 12 pixels) - and that's possibly why. Fetching data a line in advance might be a bit tricky, but I guess there are ways.
Determining how screen and sprite data are combined - this is the tricky one. There are two desirable cases:
- Plot sprite on top of background, treating sprite pixels in colour 0 as a transparent colour, and anything else as 'opaque' which overwrites background.
- Plot sprite behind background, treating background pixels in colour 0 as transparent and any other colour masking out the sprite data.
- 1bpp modes: %10000000
- 2bpp modes: %10001000
- 4bpp modes: %10101010
Code: Select all
Inputs: data, pixel_mask Set result to 0 Do 8 times: if ((data AND pixel_mask) = 0): result = result OR pixel_mask rotate pixel_mask right Output: result
Still once we've got that, we can perform both operations really easily! Let's call the function implementing that above algorithm 'mask'. Then the two sprite plotting operations described above are:
- (mask(sprite) AND screen) OR sprite
- (mask(screen) AND sprite) OR screen
- (mask(sprite) AND sprite) OR sprite
I haven't thought too much about the register model for all of this. I guess we'd need a bunch of new CRTC registers (probably better than putting a sprite table in RAM and needing extra bandwidth). The limit really is the amount of data that can be cached each row, rather than a concrete number of sprites. But maybe it'd still be better presented as 8 hardware sprites, CRTC regs &8x...&Fx, where you can set for each one:
- Sprite data address (lo/hi)
- Screen address to plot (lo/hi)
- Scanline adjust
- Sprite width
- Sprite height
- Sprite horizontal data stride
- Plot mode
Well that's an outline of my thoughts on this - what does anyone think? Does this sound like a feasible hardware project one day? I don't think it's easy by any means, and the details would need to be fleshed out properly, but it's a start to spark some discussion.
Here's where to throw some ideas around, it'd be amazing to see a hardware extension like this! This is the "fantasy Beeb graphics hardware" thread