So, first, to make sure we're talking about the same thing -- in tracked music, portamento is the process of sliding to a note from whereever we are.
In MODs, there are two kinds of portamento, depending on hardware capabilities -- impulse tracker calls them "amiga" and "linear" slides. Despite the name, the linear slides aren't linear (they're exponential).
So-called "amiga slides", used by Screamtracker 3, Fasttracker 2, and all the original trackers for the Amiga, adjust the period (1/frequency) by X per time interval, until it's arrived at the desired note. It happens to be the case that, in the middle of the range in tracked music (C2 in a MOD, C4 in ST3, C5 in impulse tracker), a speed of 0x10 corresponds to one half-step per time interval. (However, an octave above, it's one whole step per time, and an octave below, it's one quarter step per time)
The math for the Amiga slides is easy -- just something like
Code:
if (target==current) return;
if (target<current)
if (target<current-speed)
current-=speed;
else
current=target;
else
if (target>current+speed)
current+=speed;
else
current=target;
and best off, it doesn't require multiply or divide which require tricks or external hardware on the NES.
"Linear slides", used by Impulse Tracker, guarantee this correlation over the entire range, so in an appropriately configured IT song, 0x10 is always one half step per time. They are also supported by MIDI and the NES's pitch slide hardware (albeit with a different conversion)
The NES supports pitch slides on the square wave channels,
http://nesdevwiki.org/index.php/APU_Sweep.
You could do something similar to what the NES does, like
Code:
if (!--cycle) {
current = current - (current>>amount) + (target>>amount);
cycle=reloadvalue;
}
although this specific code would have problems with integer math, and the 6502 doesn't provide a particularly good way to do a variable shifts.
Or you could instead store all your current state of pitch (as i briefly entertained but decided was overkill in the end) as 8.8 MIDI-style fixed point numbers (where 60.0=C4, 60.5 is halfway between C4 and C#4, &c). In this case, you'd do your portamento directly in the MIDI-note (expontential) domain, and just convert to the NES's period hardware as necessary.