Getting dirty: The development of Verdance (Atari XE/XL32 bytes)

Introduction:

When I first got my feet wet with Atari coding back in 2022, I released a 64 byte production called Mossery for the Atari ST at AtariDays and an Atari XE/XL version to support the 150th issue of ABBUC Magazine. Now that i'm a few years older (and more experienced?) I thought it would make an interesting challenge to see if i can pull a similar effect off in 32 bytes.


Visuals:

The effect in both Mossery and Verdance consists of a relatively simple thing contains of two oscillating values that can make up circular structures. which I often call a 'minsky stepper' or 'minsky fractal', because the first time i read about it was in Byte magazine back in the day.

In generalised form you start with 2 start values for X and Y and oscillate them both using:

x += d * y;
y -= d * x;

Where in the case of integer math D can be any type of shifted integer, for example x>>4 or y>>2. In most cases these oscillators will stay fairly stable if you choose your values wisely.

Optimisations:

Usually when implementing this effect, there is a bit of juggling and shifting involved with either registers for CPU's that have them (like the Motorola 68000) or memory adresses. So I wanted to see what would be the minimal form that would still get me a pretty fractal and after some experimentation i settled on this:

x=(x+(y+value)>>1) AND 127
y=y-x

Which I was able to implement efficiently by just using the 2 system zeropage memory locations for the OSPLOT routine, namely COLCRS ($54) and ROWCRS ($55). Further optimisations were done by using the undocumented opcode LAX zp-adress (Load A and X with the contents of the zp-memory location) in combination with TXA down the line as well as using BVC branching instruction to avoid a long-branch.

Colors and pixel plotting:

Luckily the default colorvalues on the Atari XE/XL are already somewhat earthy with a red, dark-green-blue and green tints.

Location Color Value
1 709 Light green 202
2 710 Dark blue 148
3 711 Red 70
4 712 Black (Background) 0

So i could do without setting any color registers. Also i wanted to avoid setting the ATACHR memory location for the color-index and use what is left inside the accumalator directly, which I was able to do by analyzing the rom-code for OSPLOT ($f1d8) and skipping further into the code to avoid the extra setup.

Sourcecode:

I experimented with various shapes (both animating and static), but eventually settled with a static final shape as it was quite clean. Here is the final code for the intro:

; init graphics mode 15 (160x200, 4 colors)
lda #15
jsr $ef90

; Update/Draw Loop
frameloop:
lax ROWCRS ; Get (Y-Position + 3) >> 1 & 127
adc #3
lsr
adc COLCRS
and #127
sta COLCRS ; Write to Plot X-Position
txa ; Get Backup for original Y-Position from X Register
sbc COLCRS
sta ROWCRS ; Write Y-X to Plot Y-Position
jsr $f1db ; Plot Pixel, skip setting ATACHR in OSPLOT ($f1d8)
bvc frameloop

With this approach i was able to get the entire intro into the target of 32 bytes (28 bytes+4 byte header).

Conclusion:

I'm hoping that this very small and minimalistic program and writeup has been helpful to you or even might invite you to try an oldschool system like the Atari XE/XL, as the code should be relatively straightforward to understand and could serve as a starting-off point for beginners and veterans alike.

For more information, you can check out the intros at demozoo: Verdance (2025)

Return to blog overview