"we are sorry to announce that there is no funky 1k intro from gasman this year"

the intro

"apology" is a demonstration of producing 6-channel sound from the 3-channel AY sound chip of the 128K ZX Spectrum, crammed into 1024 bytes along with a couple of other bits and pieces.

Download "apology" (TAP format)

"apology" reached second place in the 1K intro competition at the Forever5 demo party.


Is it really 6 channels?


OK, how do you manage that?

In much the same way that Tim Follin managed 5 channels on the 48k beeper. The first step is to forget about the AY's built-in wave generator. Instead, each of the general-purpose registers of the Z80 (B, C, D, E, H, L) is put in charge of one channel, and they all count down simultaneously at the appropriate frequency. When one of them reaches zero, we flip the output of the appropriate AY channel - each AY channel drives two of the music channels.

What's the music?

You mean to say it's so bad that you can't tell?


Fair enough. It's (the last 16 bars of) Nimrod, from Elgar's Enigma Variations.

How much space does the music data take up?

413 bytes uncompressed (that's 59 chords at 7 bytes each).

the tracker

[A screenshot from Bachtracker. Just a bunch of numbers, really]

How do you write music for a 1K intro? With a 1K tracker, of course. Bachtracker is such a beast.

Download Bachtracker (TAP format)

It's called Bachtracker because everything you compose on it sounds like baroque organ music.

The controls:

And what it all means: The first column is a reassuring indicator of the current row. The last column is the length of the current note, in fiftieths of a second. Remember, it's written in hex like everything else. The ones in the middle show the periods of the notes - so a lower number will give a higher note. But - and this is the fun bit! - because of the way the routine works, playing higher notes will take up more CPU time and slow down everything else, meaning that all the other notes get pushed down slightly in tone. So, you have to tune each individual chord by ear.

There is no load / save feature. Just do whatever you have to do on your emulator of choice to load or save a block of memory starting from address 0x843c.

the source

Don't listen to the sceptics. Open source will rock the demo scene yet. ZX Spectrum open source even more so.

I'm not the first person to come up with the idea of Spectrum open source, of course. But traditionally, other people's assembly code has generally been 'read only', because the coding is only half the job. You've also got to deal with linking, packing and putting it all together with a nice loader, all of which discourages casual tinkering. Wouldn't it be so much nicer if you could just pick up the source of the latest demo, edit a line of code or touch up a few pixels, and then, in the twinkle of a command line, create a new version all packaged up and ready to run?

Well, now you can, and all with a few freely available tools. Isn't it a great time to be alive?

Download the source (includes both "Apology" and Bachtracker)

You are actively encouraged to play around and build upon this code. Just don't blame me if it blows up your computer, and give me credit for anything worth giving me credit for.

For the full experience, you'll also need:

the packer

In the process of writing the intro, I scoured the world in search of the ultimate PC-based code packer, even hacking together Chrust, a command line version of Hrumer's excellent Hrust utility. Then Dioniso Hernandez pointed me towards Bitbuster by Team Bomba, a real gem from the MSX scene. Its compression ratios are almost as good as Hrust, but more importantly, the decompressor was only 120 or so bytes long compared to the 256 bytes of Hrust. A quick bit of size optimisation later, and that was cut down to 89 bytes. Bitbuster Extreme was born.

Download Bitbuster Extreme (source)

Bitbuster Extreme is a completely over-the-top name for something very trivial. The original Bitbuster places a 4-byte word at the start of the compressed file, indicating the uncompressed length. This is ignored by the decompressor, so I've now chopped this out in the interests of squeezing every last byte to the limit.

"apology" links

gasman 2004-03-25