All aboard: The development of Blueprint

Introduction:

After having done two 256 byte intros for the ZX Spectrum I wanted to see if I could do something in a smaller size. So the idea for Blueprint was born.

Design

So taking the 128 byte footprint in mind, I was thinking about the kind of effects that would be possible in this size that would still allow for a bit of progression over time to take place.

This lead me to trying a parallax checkerboard type of effect, where I could see that switching up the number of layers and maybe the bitwise operations could lead to having the effect evolve over time. So I started to work out a prototype for such an effect.

An approach to linear Checkerboard calculations

Traditionally checkerboard type of effects started on 16-bit bitplane based systems like the Atari ST and Amiga, where you can quickly manipulate the individual bits on a certain layer to for example create a checkerboard pattern and let the display hardware do the actual blending and merging over the different layers for free.

This is not the case for linear videomodes, where you would need to loop through the different layers and peform a pixelcolor calculation for each of the pixels. The process for this is something like this:

Init color
Init offset
Init counter
layerloop:
* Add offset to x/y for parallax movement
* Perform bitwise operation with x/y
* Perform bitwise operation with value and color
* Shift back scalar
* Shift back counter
loop while not carry
Plot final color

The Z80 code for this would look something like this:

ld l,0 ; init color
ld e,ixl ; framecounter based offset
ld d,16 ; counter
boardloop:
ld a,c ; a=x
add e ; add offset
ld h,a ; store tmp
ld a,b ; a=y
add e ; add offset
and h ; bitwise operation with tmp
and d ; a=a&counter
or l ; merge with colorvalue
ld l,a ; move to new colorvalue
sra e ; shift back offset
sra d ; shift back counter
jr nz,boardloop

Given this process I could get by with just maxing out the default register pool available on a Z80 processor. To make it look more interesting / different to a default checkerboard setup, I switched the orientation for the entire screenspace with one of my favorite tricks (X=x+y Y=x-y).

Optimisations

I didn't want to hold back on using a custom 8x8 tilepattern as well as some proper coloring via a lookup table. So to make sure this could happen in 128 bytes, some code optimisations had to be done.

I already mentioned that I was able to use the standard register-pool for the checkerboard calculations, so that was already helpful for the size. Masking the effect would be done by using IX as a 16-bit framecounter and using the (1 byte more expensive) IXL and IXH for masking the effect and handling the progression.

Furthermore by starting the program at 0x7ffe instead of 0x8000 and jumping over the first few bytes I was able to place the colorindex lookup table directly at 0x8000 without the need of copying it over to aligned memory first.

Updates were done directly to screen instead of going through a seperate bit of memory. This was done by setting H to 0x80 (high byte of the colorindex lookup table) and setting L to the colorindex in the accumulator. Then its just a matter of use the one byte LDI command that will read the proper colorvalue from the colorindex table (HL), writes it to (DE) and increases the DE pointer.

Audio

When I had the entire effect up and running and optimised, I realised there might JUST be enough free space left to get some bare minimum AY audio going. I would just write whatever L is pointed at at the end of the screen update, then use H to skim across different bits of ROM and use that as a mask as well.

ld h,13
soundloop:
ld bc,0xfffd
out (c),h
ld b,0xbf
ld a,(hl)
and h
cpl
out (c),a
dec h
jr nz,soundloop

Obviously given its small size not the best piece of audio the hardware can produce, but it gets the job done of adding some atmosphere to the entire thing.

Release

I was able to finish this intro just in time for release at Outline 2021. I'm happy with the end result given the filesize.

For more information, you can download the intro at: demozoo.org

Return to blog overview