The Challenge: Atari Music on Amiga Without CPU
Hannibal's 3D Demo 3 beat Leonard's sin-dots record (6682 vs 6405 dots) and included a taunt: "you optimized your dots well for an Atari programmer." Leonard needed to reclaim the record while playing Atari music as a retort. But emulating the YM2149 sound chip plus Atari hardware timers consumes ~50% CPU — impossible during a dot-rendering race.
The Hardware: YM2149 vs PAULA
The YM2149 generates square waves, noise, and has a shared envelope generator. PAULA plays 4 independent 8-bit PCM samples with per-channel volume. They're fundamentally different.
The Plan: Offline Precomputation + PAULA Attached Voices
Leonard wrote a PC tool to simulate an Atari .sndh music file frame-by-frame at 50 Hz, extracting period and volume for each of the 3 YM voices. These values are converted to PAULA-compatible period/volume and stored in a data file. On the Amiga, each frame the program reads a few values and updates 3 PAULA channels looping a square wave sample. No CPU time for emulation.
The Problem: MadMax Buzzer Sounds Terrible
Pure square waves (e.g., Buggy Boy) sound bland. To get the rich, sweeping "MadMax Buzzer" effect used in tracks like "Leavin Teramis", the YM uses its envelope generator as a sound source, combined with a detuned square wave. Emulating this with PAULA's attached voice mode (where one voice modulates another's volume) produced coarse results because the modulator data runs at half the sample rate.
The Eureka Moment: Swap the Roles
Instead of storing the triangle envelope as the 16-bit modulator (which had low resolution), Leonard stored the triangle envelope as the 8-bit PCM sample and used a square wave as the modulator. The square wave only needs high/low values (64/0), so the low-rate modulator doesn't hurt. The 8-bit PCM sample now has full resolution for the triangle shape.
Implementation Details
Square wave sample (8-bit):
AmigaSquareWave:
dc.b $7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$00,$00,$00,$00,$00,$00,$00,$00
Triangle envelope as 8-bit PCM:
AmigaTriangleEnvelope8bit:
dc.b $00,$00,$00,$00,$01,$01,$01,$01,$02,$02,$03,$03,$04,$05,$06,$07
dc.b $09,$0b,$0d,$0f,$12,$16,$1a,$1f,$25,$2c,$35,$3f,$4b,$59,$6a,$7f
dc.b $7f,$6a,$59,$4b,$3f,$35,$2c,$25,$1f,$1a,$16,$12,$0f,$0d,$0b,$09
dc.b $07,$06,$05,$04,$03,$03,$02,$02,$01,$01,$01,$01,$00,$00,$00,$00
Square wave as 16-bit modulator (values 64 or 0):
AmigaSquareWaveModulator:
dc.w 64,64,64,64,64,64,64,64,0,0,0,0,0,0,0,0
The Result
With the roles swapped, the emulated MadMax Buzzer sounds almost identical to the reference. The technique uses 3 PAULA voices for YM square waves and the 4th as modulator, leaving the CPU free to render sin-dots. Leonard plans to use this in his next record attempt.
Why This Matters
This is a masterclass in creative hardware abuse. Leonard exploits an obscure, unused PAULA feature (attached voice volume modulation) to solve a real problem. It demonstrates that deep understanding of hardware quirks can yield elegant, zero-overhead solutions. For modern developers, it's a reminder that sometimes the best optimizations come from rethinking assumptions — like swapping the roles of data and control.




