I post its render loop and properties, might inspire someone to go on with it. Maybe later even me, but I rather work on polishing my 7cy / pixel ideas (it is a quite tedious work to get the sprite engine properly tested and running).
First let's see the code:
For the 4 cycles / pixel variant:
Code: Select all
cblockxx:
out PIXOUT, r18/r19 ; Pixel 0
ld ZL, X+ ; Load tile index
cp ZL, r15 ; r15: ROM (low) / RAM (high) tile split point
out PIXOUT, r18/r19 ; Pixel 1
brcs .+18
ld YL, X+ ; Load attribute pair of tile
out PIXOUT, r18/r19 ; Pixel 2
mov ZH, r25 ; RAM tiles base
ld r20, Y
out PIXOUT, r18/r19 ; Pixel 3
add ZL, r17 ; RAM tiles wrapping offset
ld r0, Z
out PIXOUT, r18/r19 ; Pixel 4
rjmp .+16
mov ZH, r24 ; ROM tiles base
out PIXOUT, r18/r19 ; Pixel 2
add ZL, r16 ; ROM tiles wrapping offset
ld YL, X+ ; Load attribute pair of tile
out PIXOUT, r18/r19 ; Pixel 3
lpm r0, Z
out PIXOUT, r18/r19 ; Pixel 4
ld r20, Y
swap YL
out PIXOUT, r18/r19 ; Pixel 5
mul r0, r23 ; r23: Size of code blocks in words (32)
movw ZL, r0
out PIXOUT, r18/r19 ; Pixel 6
ld r21, Y
add ZH, r22 ; r22: Base of code blocks (high 8 bits only)
out PIXOUT, r18/r19 ; Pixel 7
movw r18, r20
ijmp
Code: Select all
common:
out PIXOUT, r3 ; Pixel 3
cp ZL, r15 ; r15: ROM (low) / RAM (high) tile split point
brcs .+10
mov ZH, r25 ; RAM tiles base
add ZL, r17 ; RAM tiles wrapping offset
out PIXOUT, r4 ; Pixel 4
ld r0, Z
rjmp .+8
mov ZH, r24 ; ROM tiles base
out PIXOUT, r4 ; Pixel 4
add ZL, r16 ; ROM tiles wrapping offset
lpm r0, Z
out PIXOUT, r5 ; Pixel 5
ld r20, Y
mul r0, r23 ; r23: Size of code blocks in words (12)
out PIXOUT, r6 ; Pixel 6
swap YL
ld r21, Y
movw r18, r20
out PIXOUT, r7 ; Pixel 7
movw ZL, r0
add ZH, r22 ; r22: Base of code blocks (high 8 bits only)
ijmp
cblockxx:
out PIXOUT, r18/r19 ; Pixel 0
mov r3, r18/r19 ; Pixel 3
mov r4, r18/r19 ; Pixel 4
mov r5, r18/r19 ; Pixel 5
mov r6, r18/r19 ; Pixel 6
out PIXOUT, r18/r19 ; Pixel 1
ld ZL, X+ ; Load tile index
ld YL, X+ ; Load attribute pair of tile
out PIXOUT, r18/r19 ; Pixel 2
mov r7, r18/r19 ; Pixel 7
jmp common
- 1 bit per pixel.
- True palettized attribute mode (fg & bg colors individually selectable from a 16 color palette)
- Needs a 256 byte palette buffer (the usual ld + swap + ld technique)
- Terminates with timer interrupt (like Mode 13, rightmost pixel column is a bit fat unless abusing the interrupt vector table)
- The code block set has to be aligned at a 256 word boundary
- The VRAM takes 2 bytes per tile: a tile index and an attribute pair. Typical VRAM usage is so around 2Kb (40x25 tiles on 4cy / pixel)
- Arbitrary ROM tile / RAM tile split point (low tile indices: ROM tiles, high tile indices: RAM tiles)
- Tileset size may be any power of 2 (power of 2 constraint persists since it is not possible to carry between ZL and ZH)
- No scrolling support
The 4 cycles / pixel variant may be used to re-create some Hi-Res Commodore games (no sprites though), and for anything text mode'ish (up to 45x28 8x8 tiles). The 5 cycles / pixel variant may be assumed to have square pixels, and is suitable for re-creating a ZX Spectrum like experience.
The bigger deal of course is the 4 cycles / pixel variant, it doesn't seem like such was done before here, maybe expect for simple monochrome graphics. This could probably replace code tiling for high resolution, of course expect the ultra high resolution (480 pixels, 3 cycles / pixel) of Mode 9.
For the latter by a similar technique with no attributes and only RAM tiles is possible (even leaving 4 cycles free, but that's not useful for attributes since there is no way to load them in the proper place, the ijmp filling the whole 2 cycle inter-pixel gap), maybe it could be used by preloading the tile data into RAM on every scanline, but it didn't seem worth any further experimenting.
Tileset sizes: a tile takes 8 bytes. So, due to the power of 2 limit, you may typically have 2K (256 tile) sets in ROM, and maybe 1K (128 tile) or 512b (64 tile) sets in RAM. The layout is framebuffer-like (since ZL directly indexes the tiles, the offset added to it, and the proper setup of ZH can realize the proper row increment).
An interesting possiblity may be splitting the tile indices and the attributes (by loading one of them by abusing the stack, due to the Timer interrupt termination it is a bit tricky though!), which may enable you saving the RAM of tile indices when using a framebuffer (may be useful for displaying larger pictures loaded off of SD card for example, like I did with the 2bpp Multicolor mode in my Mode 74 thread).
So just if anyone is interested, here they are!