Seyed Masoud Hosseini · Overview · Study log · Ideas · Transcript · RSS feed
Embedded Systems, 6502 breadboard computer · Lecture 29 of 29 · 21:56
29 of 29: Sound synth with a 6502
Study guide
What this lecture covers
The previous BEEP command could only produce plain square waves at different frequencies. This lecture extends the sound hardware so the computer can vary the duty cycle (the ratio of on-time to off-time within each cycle), producing noticeably different tones at the same pitch, and adds a low-pass filter to approximate triangle and sawtooth waves.
It follows directly from the earlier video that added BEEP to Microsoft BASIC using the 6522 VIA's timer. Getting varying duty cycles working requires wiring the 6522 into the interrupt line alongside the existing serial UART, so the lecture also covers how to safely combine two interrupt sources with diodes and how to distinguish which device caused a given interrupt.
Key ideas
- Duty cycle changes the sound: even a fixed-frequency square wave sounds different depending on what fraction of each cycle it spends high versus low, as demonstrated on a signal generator.
- Two intervals per cycle: producing an arbitrary duty cycle means reloading the 6522's timer with a different value for the "on" half-cycle than the "off" half-cycle, changing it on every timer interrupt.
- Combining interrupt sources: since the 6502's IRQ line is a single wire, diodes from both the UART and the 6522 let either chip pull it low without one chip's totem-pole output fighting the other's.
- Identifying the interrupt source: the interrupt handler must check each chip's status register (bit 7) to determine whether the UART or the 6522 timer caused the interrupt, since more than one device can now trigger it.
- Acknowledging the 6522's interrupt: writing to the timer 1 latch high byte (which the handler already does to reload the timer) both sets up the next half-cycle and clears the interrupt flag.
- sound1 / sound2 variables: two zero-page values hold the timer intervals for the two phases of the wave, read from a phase check on port B bit 7.
- Interrupt enable register: timer 1 interrupts must be explicitly enabled ($C0) when starting a beep and disabled ($40) when stopping it.
- Low-pass filtering: adding a capacitor after the volume potentiometer smooths the square wave's edges, approximating a triangle wave for a mellower sound.
Walkthrough
Duty cycle and waveform shapes (0:01)
A signal generator hooked to the same LM386 amplifier and speaker demonstrates that changing a square wave's duty cycle (50% down to 10%) produces different sounds at the same frequency, and that triangle and sawtooth waves sound different again from square waves.
Wiring the 6522 into the interrupt line (2:02)
To vary the duty cycle, the timer must reload with a different value on each half-cycle, driven by a timer interrupt. Since the IRQ line was previously only connected to the UART, a diode is added from the 6522's interrupt pin so either chip can pull the shared IRQ line low without conflict, following the approach described in the 6522 data sheet for its totem-pole output.
Distinguishing interrupt sources (7:04)
With two possible interrupt sources, the handler now checks bit 7 of the UART's status register before assuming the interrupt came from incoming serial data, then checks bit 7 of the 6522's interrupt flag register to detect a timer 1 expiration.
Alternating the timer interval (9:07)
Two new zero-page variables, sound1 and sound2, store the interval for each half-cycle. The handler reads port B's bit 7 to determine which phase just finished, then reloads the timer latches from the appropriate variable for the next half-cycle, producing an asymmetric duty cycle.
Extending BEEP and enabling interrupts (13:11)
The BEEP instruction is extended to take independent values for the two half-cycles, storing them into sound1 and sound2 using the same parameter-parsing routines as before. Starting a beep now also writes to the 6522's interrupt enable register to turn on timer 1 interrupts, and stopping a beep disables them.
Testing different duty cycles (17:14)
After flashing the updated ROM, calls like BEEP 1136,100 and BEEP 2022,100 produce the same 440 Hz pitch with clearly different timbres, confirmed on the oscilloscope and by ear across several duty-cycle examples.
Approximating other waveforms (19:16)
Adding a capacitor after the volume potentiometer forms a low-pass filter with it, rounding the square wave's edges into something closer to a triangle wave and producing yet another set of sounds from the same underlying signal.
Before you watch
- Watch the previous video, which adds the BEEP instruction and gets a basic square wave working from the 6522's timer.
- Be familiar with 6502 interrupt handling and the existing serial-interrupt code from the input buffering videos in this course.
- Basic familiarity with RC low-pass filters helps for the final section, though it's explained from first principles.
Check your understanding
- Why does changing a square wave's duty cycle change its sound even when the frequency stays the same?
- Why are diodes needed to let both the UART and the 6522 share the same IRQ line?
- How does the interrupt handler decide which chip caused a given interrupt?
- What do the
sound1andsound2variables represent, and how does the handler choose between them? - Why does adding a capacitor after the potentiometer turn a square wave into something closer to a triangle wave?
From the YouTube description
More 6502: https://eater.net/6502
Support these videos on Patreon: https://www.patreon.com/beneater or https://eater.net/support for other ways to support.
------------------
Social media:
Website: https://www.eater.net
Twitter: https://x.com/beneater
Patreon: https://patreon.com/beneater
Reddit: https://www.reddit.com/r/beneater
Special thanks to these supporters for making this video possible:
Adrien Friggeri, Aleksey Smolenchuk, aliceitc, Anthony Weems, anula, Axel Hanikel, Ben, Ben Cochran, Ben Kamens, Benjamin D. Williams, Benjamin Elder, Benjamin Keil, Benji Bromberg, Bill Cooksey, Binh Tran, Bradley Stach, Brian Haug, Carl Fooks, Carsten Schwender, Casten Riepling, Chad Fertig, Chai, Chris Anders, Chris Lajoie, Craig Hawco, criis, Cristi Cobzarenco, Daniel Tang, Dave Westwood, David Clark, David Cox, David Dawkins, David House, David Sastre Medina, David Turner, Dean Winger, Deep Kalra, DemoniacDeath, Dennis Henderson, Derek Chandler, Dilip Gowda, Dirk Sperling, Dmitry Guyvoronsky, Dustin Schoenbrun, Dzevad Trumic, Emilio Mendoza, Eric Dynowski, Erik Chancy, Ethan Sifferman, Eugene Bulkin, Evan Serrano, Eveli László, garmata, George Harris, George Miroshnykov, Glen Jarvis, Glenn Davidson, Gregory Burns, GusGold, Henry Lerner, Ingo Eble, Isaac Parker, Jack McKinney, James Capuder, James Chacon, Jason DeStefano, Jason Grim, Jason Thorpe, JavaXP, Jaxon Ketterman, Jefferson Hunt, jemmons, Jesse Miller, Jim Kelly, Jim Knowler, Jim Rees, Joe Beda, Joel, John Haugabook, John Rivoire, Jon Dugan, Jonn Miller, Josh Smith, Justin Williams, Kai Wells, Kefen, Kennard Smith, Kenneth Christensen, Kristian Høy Horsberg, Kyle Kellogg, Lambda GPU Workstations, Larry Scherr, László Bácsi, Lithou, Marcel Wysocki, Mark Day, Mark Frankford, melvin2001, MICHAEL SLASS, Michael Tedder, Michael Timbrook, Michele Milani, Mike G, mikebad, Miles Macchiaroli, Mlok Karel, Nate Welch, Nicholas Counts, Nicholas Moresco, Nick Chapman, Nikki Pearson, Olivier HUBER, Örn Arnarson, Owen Arnett, Pat Nakajima, Paul Heller, Paul Pluzhnikov, Pete Dietl, Philip Hofstetter, ProgrammerDor, Ralph Irons, Randal Masutani, Randy True, raoulvp, real_huitz, Richard Wagoner, Robert Diaz, Robert Walsh, Robey Pointer, Roland Munsil, Ryan, Ryan Morrison, Sachin Chitale, Sagnik Bhattacharya, Sam Sturgis, Scott Holmes, Sean Patrick O’Brien, Sebastian Kopeć, SergeantBiggs, Sergey Kruk, Sergey Ten, SonOfSofaman, sorek.uk, spookybassoon, Stanley Benoit, Stefan Nesinger, Stéphane Dumont, Stephen Kovalcik, Stephen Riley, Steve Jones, Steve Harris, Tate W, This person's name is too hard to pronounce, Thomas Eriksen, Tim Oriol, Tim Sanders, Tim Walkowski, Tom, Tom Smith, tremors08, Trevor Johnston, Trey Webb, tryonlinux, Tyler Latham, Victor Kazakov, Warren Miller, Wraithan McCarroll
