Ahle's signal generator triangle wave code
I'm looking for some pasm triangle wave code.
I've gotten Johannes Ahlebrand's signal generator code trimmed down to almost the simplest form that still generates a nice clean triangle in the same way as his original generator module did, but there's a programming trick in it that I just don't get.
In this code, how is it that the label "out" also serves as a variable? What's going on there?
I've gotten Johannes Ahlebrand's signal generator code trimmed down to almost the simplest form that still generates a nice clean triangle in the same way as his original generator module did, but there's a programming trick in it that I just don't get.
In this code, how is it that the label "out" also serves as a variable? What's going on there?
CON
_CLKMODE = xtal1 + pll16x
_XINFREQ = 5_000_000
AUDIOPIN = 8
ADC_PIN = 9
PUB main | duty_mode
damplevel := 0
duty_mode := %00111 << 26
regCounter := duty_mode | AUDIOPIN | (ADC_PIN<<9)
noiseValue := $1000_0000
set_pindir := (1<<ADC_PIN) | (1<<AUDIOPIN)
frequency := 80 * (536_870_912 / 10_000_000) 'Generate a 80 Hz triangle wave
cognew(@triangle_wave, 0)
repeat
DAT org 0
triangle_wave
mov dira, set_pindir
mov ctra, regCounter
out mov ctrb, noiseValue
'───────────────────────────────────────────────────────────
mainLoop
sar out, damplevel
add out, dcOffset
mov frqa, out
mov frqb, frequency
absneg out, phsb
shl out, #1
sub out, dcOffset
jmp #mainLoop
'───────────────────────────────────────────────────────────
dcOffset long 1<<31
regCounter long 0-0
noiseValue long 0-0
set_pindir long 0-0
frequency long 0-0
damplevel long 0-0
{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Propeller Signal Generator v1.2 (C) 2012 Johannes Ahlebrand │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ TERMS OF USE: Parallax Object Exchange License │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │
│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │
│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│
│is furnished to do so, subject to the following conditions: │
│ │
│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│
│ │
│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │
│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │
│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}

Comments
Once the init opcode is executed, the RAM may be used as a VAR,but it does hurt the eyeballs...
Hehe, oh the freedoms of assembler ...
I guess the reason for it is, because it is possible! There is no reason for saving space this way when just a TINY bit of the cog RAM is utilized by the signal generator anyway, I could have reserved a variable instead. In Retronitus I did the same thing, but it REALLY is a tight fit, so there is a lot of "tricks" like that in there.
/Johannes
Retronitus is a work of art, by the way! It's amazing.