Mostly, the CPUs didn't have to tick out the sound pulses; they had an ASIC to generate the tones - you just had to tell it to turn on, which tone, and any modulation it was capable of. It would stay on until turned off.
So what you did in software is watch the time, and set or disable the tone generators at appropriate times.
Typically you made a table of tones+modulations and time durations, optimized for compression. The on-vertical-blank subroutines crawl that table, timing out each note, and telling the ASIC to change or quiet notes at a particular time.
A diatonic scale is 7 notes per octave, a chromatic scale 12... so 5 bits (31+silence) supports 2.5-4.5 octaves depending on how many flats, sharps or keys you support. Add 3 bits for duration and you've packed a primordial channel into a table of 1 byte width, in a super simple programming language. I mention that because you could make the "language" more complex if it makes the table smaller.
MIDI has way more complexity than is needed; there's no reason to support it when table space and code bandwidth is at a premium.