Chillobits writeup

Yeah, so with all the great feedback on our Revision contribution, I felt inspired to do a little technical writeup. Maybe even to inspire more Amiga coders to code something else than rotozoomers and vector cubes 🙂

I had a long scene hiatus from around 1994 to 2017, so there are of course lots of demos I don’t know about. But one of the concepts I had for this demo was, can I make a whole demo with only routines noone has made (at least as far as I know) on Amiga yet? I thought the answer was YES! So most of the parts in the demo are coded by me, based on that concept.

Then I invited Perplex and Leuat to do a part each, and they both made twister scrollers. Oh well. At least they were nice ones 🙂

The parts I describe here are just the ones coded by me, just giving a cursory description of the others.

Not going to go into detail on the infrastructure, but we did use the trackloader from RockLobster, which worked without issue. Only one small weird thing happened, sometimes there seems to be a weird interaction with the replayroutine early in the mod, making a weird squeaking sound. It was in the compo recording but not in my own one.

  1. The startup – “Basic fader”

It seems many people are referencing this to Andromeda D.O.S., I was actually thinking more about Wild Copper Megalo Demos with this one. And of course, every C64 demo has one of these, so why not do a proper one on Amiga? Nothing special in the code, just took an AmigaDOS image and a routine walks through it, masking out the letters and turning them into bobs. For the logo, only the idea is interesting, not the implementation. You just start the spinners at the end and count backwards, with random speeds. If that makes any sense. Then I had Pal draw over it without changing the contours, which turned out very nice.

2. The cave

I like the wipe routine here, it uses halfbrite plus bitplane 5 because the image is only 16 colors. The actual tiles were computed with javascript using a 2d canvas, 124 frames of 32x32x2.

3. The line circle… thing…

I had this idea in my head that wouldn’t go away, about a circle made of radiating lines, where the lines were separated not by a constant radial distance but something on a sine wave, the sum of which over the whole circle is 0, meaning the circumference is still a complete circle. I made a prototype in javascript first, posted it here:

Then I had to hack up the Player 6.1a replayroutine a bit, because I just wanted to react on the the bassdrum and snare, and Jogeir reuses the same track for lots of percussion instruments. Then separate out the same drawing area into a second bitplane with a bit of offset, making a nice interference pattern, and we’re done.

4. Pal balls

This was Pal’s idea, not mine, so I just took the shortest route to the target, calculating all the collisions in js, generating a datafile for x/y positions and colors of each ball for each frame. Turned out to be 58K for 1000 frames (20 seconds). The Amiga side is a fairly dumb replayroutine using the blitter, which leaves plenty of rastertime for precalcing the next part.

5. Star plate/Kaleidoscope

So how many dots CAN you plot? Probably more than this, but this is 1040. Bitplane 2 is a delayed version of bitplane 1, and bpl3+4 are the same ones upside down. Shrinking DDFSTART/DDFSTOP to a screenwidth of 20 bytes saves some DMA and also make clearing faster. Uses blitter for clearing. The plotter starts in the middle, plotting more and more dots the farther out it goes. It goes around the circle with a speed that increases with the distance from the center, and plots dots at intervals. Innerloop was pared down to 10 instructions, plus one more when it skips to the next larger radius. Using longword operations for precision. This routine looks best when left to run over a few minutes, which wasn’t an option here, so it skips forward to the best parts, or at least some good parts…

Oh, and this one also has a dwitter:

5. Bouncy ball

I really like this one! The code is not as interesting though, it was generated in javascript as a sequence of 474 frames, each being a set of 256 tuples containing a start and end point for bitplane data. With some simple compression tricks it weighs in at 167K in memory, but Cranker cranks it down to 22K. The “replayroutine” on the Amiga side precalculates a set of 160 bitplane lines, the first one being blank, the second one having 2 pixels in the middle, the third one having 4 pixels in the middle et cetera until we get to 320 pixels. Then for each frame we need to select the correct line with the copperlist, and set the scrollregister if necessary. The copperlist has a wait for each line, then sets BPL2PTL and BPLCON1. Of course you need to make sure that your precalculated lines are all in the same 64K memory block or you’ll have to set BPL2PTH too, which would be a waste. Add some bobs (also Javascript-calculated in this case) in bitplane 1 and 3 and we’re done. Did it that way to save some small coding time, since the scroll value for those bitplanes is separate and you don’t have to adjust. Otherwise we could of course have 16 color bobs. Can you tell the deadline is approaching? 😀 This also leaves room for loading, decrunching and precalcing the next part.

6. Weird circle with some kind of color inside, transitioning into the creditsfaces

Yeah, the circle basically uses the same routine as the next one, so not going into it. The faces use the same basic idea as 5. (but were made a long time ago) except in 6 bitplanes. Since you can’t use the scroll registers, there are 16 copies of each precalculated line, each shifted one more pixel to the right. Face data is basically 256 bytes for each face, each representing one rasterline (and saying which precalculated line to select on that line). Doing some precalced transforms on those facedataframes for the rotation. This setup lets us use Dual Playfield mode ftw, since it’s always trivial to know the z position of each face (it doesn’t change at all). So we can use 8 sprites to draw the names on top. This is the same sprites covering all the vertical space, just changing the sprites x position with the copper every few lines. Of course this makes the copper update routine a bit more complicated, and this code was a mess at the end…

7. Nasevase (or “2 faces one cup” as psenough said)

Perplex’ idea, based on the wellknown optical illusion of 2 faces and a vase. We just reuse the routine in 6. to render only 2 faces, then took a screenshot and had Pal do another drawover without changing the outline. This is just goofy and fun and I love it 🙂 Then it techtechs out into oblivion! Good times.

8. One School

Just one bitplane, in precalc copied 16 times at increasing right shift values. The actual drawing routine selects the correct version for each plane, in lieu of setting a scroll register (since we don’t have 6 separate scroll registers). Easy peasy, and takes no raster time, so it loads the next few parts from disk meanwhile.

9. Double twister

This one was made by Leuat in Turbo Rascal. This is basically a programming language that spits out assembler. Works for a lot of platforms, and Amiga support was added quite recently. But check it out for yourself if it sounds intriguing to make the same effect on Amiga, C64 and VIC 20 with the same code 🙂

We had us a time plugging his generated code into the rest of the demo, but we worked it out. I have really no idea how he made that twister.

10. Space twister

This is Perplex’ part. The image is 32 colors lores, and the twister is made of attached (16 color) sprites. Since the palette is shared, much thought was given to color selection. The scroller works by using font segments, a technique well known on the C64 which I’m not going to detail.

Sprite positions and graphics are both updated using pregenerated copper subroutines, so only COP2LCx needs to be modified (2x) per line.

11. Oscilloscope head

Another awesome 32 color pic by Pal. I added a subtle blinking effect to the lights below the screen. Probably noone noticed, but I think that kind of effect has a place in demos, not everything has to be in your face with a sledgehammer. Fast mood, slow mood. This one sends the memory pointers for the palette and the bitplane data to the next part for some very bespoke goodness. The next part starts rendering just inside the screen, fades out the image and then zooms in. This is probably the most complicated transition in the demo. I felt that doing this all over added a lot to the flow of the demo though, making it feel like a whole even if many parts are NOT connected at all.

12. Oscilloscope

This one uses the oscilloscope option in The Player 6.1a. The plotter is based on the one-dimensional oscilloscopes used in Dizzy Tunes, but I couldn’t reuse that old replayroutine since it’s not compatible with this module. It has a twist though: Instead of plotting the sample value on x axis and linearly increasing the value on the y axis, we take a new sample value at an offset from where we got the x value, and use it as the y value. The offset can be varied to create different patterns. In this case I used a value calculated from the pitch, plus a sine value. Thanks to Karl Anders for teaching me this trick 🙂 A very crude version of this was in Rebels “Introduction to Seduction” by Dweezil. I think mine is nicer though. It works like pure magic when you have some high quality samples, and this is my favourite routine that I made on Amiga, ever. So I was a bit bummed when the Revision stream cut it off in the middle. Well, we mustn’t delay the block of mindnumbingly similar 8 minute sets of flashing 3D-puke with llamacore music, must we.

Anyway, back to the code: because of this offset, and in some cases plotting more dots than the sample window actually has, I had to make a routine that makes some room in the sampledata and fills it with the repeat (just for repeating instruments). Otherwise the plotter would overrun the sample and start plotting from the next sample – not pretty I can assure you.

Add some variations and circle movements, some greetings below it, and we’re done. Except one thing, I added a mode where if you hold down the right mousebutton during boot, it loads up Jogeir’s module in this part. It looks even nicer with this routine, I thought 🙂

Hope you enjoyed that (If you’re still reading, I suppose so!) and maybe it even inspired you. Never stop thinking, feeling and coding!

Join the Conversation


  1. Great writeup! This was inspiring indeed. The last months I have been on a nostalgia trip so deep that I have fired up the assembler again. I have been a fan of your work since “Look, no bitplanes!” (which has an amazing atmosphere, I must say).

    What I am wondering about now is your setup for coding for A500 in 2021. What toolchain do you use, and would you care to share it? I have experimented with cross-assembling with vasm, but I really miss the AsmOne/AsmPro live debugger, which I depended on back in the days. If I run AsmPro in UAE I have occasional crashes, and also miss the modern dev setup I am used to. What do you use?


    1. Thanks for your kind words. For development I based my setup on this:

      The included demo startup code is very useful (the code I used in 1990 was… not nice) and there are tools for converting graphics etc. I made some small modifications to the BuildAndRunDemo script to fit my workflow.

      For debugging you can set a breakpoint and use the WinUAE debugger, but it’s not ideal as you don’t get any symbol info. I also miss the ease of debugging natively… But there are some WinUAE tools to print debug messages etc, which mitigate the problem.

      And of course I substituted Visual Studio Code for the clunky old Visual Studio. There are some really nice VSCode plugins available, just search for Amiga and 68000.


Leave a comment

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create your website with
Get started
%d bloggers like this: