4.8 KiB
---js const title = "Aerations - Hacking Furnace to do stuff"; const description = "Some ramblings about timers"; const date = "2025-09-17"; const tags = ["atari st", "timer fx", "timers", "demoscene"]; const draft = true;
back in July this year, we released "Aerations" at the Sommarhack 2025 demoparty. with it, we demonstrated the ability to compose Atari ST music, with classic timer effects like PWM and SyncBuzzer, and the ability to export it under a format usable on real hardware (thanks Natt!)
developing the tech required for it was a real pain in the arse... it turns out that the ST is janky, and therefore also has janky audio, and we needed to emulate this jankness in the tracker
timer effects: what? how?
generally speaking, a timer is a mechanism that lets an action be done at a preset time. on computers, it lets the CPU do things periodically, and if it is able to interrupt the CPU, allows actions to be executed automatically at regular, periodic intervals.
on every Atari ST ever made is a chip called the MC68901: Multi-Function Peripheral (MFP), and this chip provides an USART, an interrupt controller, and most notably, 4 timers. these timers are at the heart of timer effects (hereby called timer FX).
what is timer FX? on the Atari ST, it means any effect that messes with the YM2149 sound registers. this means it can be used to write to a register at regular intervals, producing audible effects (like frequency modulation, amplitude modulation, etc...). although there are a variety of effects that can be done with this, for Aerations in particular, we only used 2:
- PWM (Pulse Width Modulation)
- SyncBuzzer
pulse width modulation
PWM is amplitude modulating the YM square generator output with the timer. the timer generates a square wave by switching between minimum amplitude and maximum amplitude at the timer period, and the resulting wave which is not always in phase with the square output of the YM, and when this wave is applied to the YM output by amplitude modulation, the 2 waves being out-of-phase will cause one wave to "shadow" the other (this happens when the square edge of either source is 0). the following ASCII diagram shows this:
+------+ +------+ +------+ +------+
| | | | | | | | [Timer-generated square]
---+ +------+ +------+ +------+ +---
+------+ +------+ +------+ +------+
| | | | | | | [YM2149 square generator]
+------+ +------+ +------+ +------+
+---+ +---+ +---+ +---+
| | | | | | | | [Amplitude modulated, YM+timer]
---+ +---------+ +---------+ +---------+ +------+
of course, you will not always get a stable pulse wave, since the timer has a different clock and a frequency that is not always equivalent to the YM2149 frequency. since both frequencies are not equivalent, they will go out of phase, causing phasing, and thus causing pulse width modulation because the part of the square wave it shadows is constantly changing.
since it works by amplitude modulation, the minimum and maximum amplitude can be any value one desires, allowing for less of the YM square wave to be shadowed, making for a very subtle undertone in the instrument (wow this sentence sucks).
in most drivers, this is implemented as 2 timer handlers, and these are alternated between every time the timer causes an interrupt. timer handler A will change the vector to timer handler B, and timer handler B will change the vector back to timer handler A. in theory, this could be extended to an arbitrary length, and this is actually how you can make wavetables. however, we do not use this in the song and the effective frequency of the timer- generated waveform gets lower every time you add more steps to the waveform.
SyncBuzzer
SyncBuzzer is rather simple in contrast to PWM described above. the YM2149 (and its descendant, the AY-3-8910) have a peculiar behaviour, where if you write any value to register $0D (envelope shape register), it causes the envelope to reset from the beginning, and the phase is also reset. it is simpler, because we only need one timer handler to just reset the envelope by writing the current envelope shape to it again. this on its own isn't particularly exciting, so you need to run your timers at a different frequency from the envelope (or vice versa) in order to get a buzzy tone from the envelope.
the bass in Aerations is actually SyncBuzzer, but the timer is running at a different frequency, which is a multiple of the current bass frequency.