Losing my mind, assembly variable addresses updating wrong variable (Free Beer)
I've been wanting a high resolution Digital Oscillator set-up for my analog synthesizer project. using the two 32bit counters in each cog to generate ramp waves that is fed into my 24bit DAC.
I had it working in spin fine with MIDI input and 6 voices but the samplerate was far too slow ~8KHz so i re-worked it in assembly but passing the main hub ram addresses never seemed to align properly with cog ram.
I've been debugging this for days and have now started from scratch several times but in PASDebugger it shows for example:
-MOV Sum, #12
will place 12 into Waittime
what am i doing wrong, originally i wanted interaction with hub ram to a mixer routine and im pretty sure i did it correctly but now its stripped to just one cog ,2 oscillators, and output directly but it still wont get jump & variable locations correct. ARRGHHHHHHHHHH, pleease help. I'll post a six pack to your house if you can fix it.
I had it working in spin fine with MIDI input and 6 voices but the samplerate was far too slow ~8KHz so i re-worked it in assembly but passing the main hub ram addresses never seemed to align properly with cog ram.
I've been debugging this for days and have now started from scratch several times but in PASDebugger it shows for example:
-MOV Sum, #12
will place 12 into Waittime
what am i doing wrong, originally i wanted interaction with hub ram to a mixer routine and im pretty sure i did it correctly but now its stripped to just one cog ,2 oscillators, and output directly but it still wont get jump & variable locations correct. ARRGHHHHHHHHHH, pleease help. I'll post a six pack to your house if you can fix it.
{32bit to 16bit dual oscillator cog}
VAR
long oscaddr
long astep
long bstep
long bits
PUB start(_resolution)
astep := 50_000
bstep := 0
bits := _resolution
oscaddr := @astep + (@bstep<<16)
cognew(@entry, @oscaddr)
PUB seta(_astep)
astep := _astep
PUB setb(_bstep)
bstep := _bstep
DAT
org 0
entry
begin rdlong Addr, par
mov CTRA, Cntset 'reset counters
mov CTRB, Cntset
mov DIRA, Pinset
mov Clktime, CNT
waitcnt Clktime, Waittime
mov Aadd, #2 'clear increase value on every clock
mov Badd, #4
mov FRQA, #0 'clear increasers
mov FRQB, #0
mov PHSA, #0
mov PHSB, #0
mov Aaddr, Addr
mov Baddr, Addr
and Aaddr, LSB
shl Baddr, #16
mov Clktime, CNT
waitcnt Clktime, Waittime
startLoop mov Sum, #0
mov Bval, #0
rdlong Aadd, Aaddr
cmp Preva, Aadd WZ
if_z jmp #noChangeA
mov Prev, Aadd
mov FRQA, Aadd
mov PHSA, #0
noChangeA rdlong Badd, Baddr
cmp Prevb, Badd WZ
if_z jmp #noChangeB
mov Prevb, Badd
mov FRQB, Badd
mov PHSB, #0
noChangeB tjz Preva, #addB
mov Sum, PHSA
shr Sum, #16
addB tjz Prevb, #update
mov Bval, PHSB
shr Bval, #16
update add Sum, Bval
shl Sum, #8
mov OUTA, Sum
jmp #startLoop
Addr long 0
Aaddr long 0
Baddr long 0
Aadd long 0
Badd long 0
Cntset long %0_00001_000_00000000_000000_000_000000 'cnt settings
Pinset long $00FFFF00 'pins 31-0
Sum long 0
Bval long 0
Waittime long 10_000_000
Clktime long 0
Preva long 0
Prevb long 0
LSB long $0000FFFF
MSB long $FFFF0000
fit
{16bit MIDI Synth Routine 20:01, 04/03/2014}
CON
_clkmode = xtal1 + pll16x 'gives 64 MHz
_xinfreq = 4_000_000
'48KHz sample rate, 1250 cycles per sample
SAMPLE_RATE = 32_000 'Hz
DA_BITS = 8 'Resolution
SAMPLE_DELAY = 64_000_000/SAMPLE_RATE
doNoteOn = $00000001
doNoteOff = $00000002
doAftertouch = $00000004
doController = $00000008
doProgramChange = $00000010
doChannelPressure = $00000020
doPitchWheel = $00000040
doSysex = $00000100
doMTC = $00000200
doSongPosPtr = $00000400
doSongSelect = $00000800
doTuneRequest = $00001000
doMidiClock = $00002000
doMidiTick = $00004000
doMidiStart = $00008000
doMidiContinue = $00010000
doMidiStop = $00020000
doActiveSense = $00040000
doReset = $00080000
OBJ
debug : "Parallax Serial Terminal"
midi : "MidiIn"
f : "Float32"
osc : "AsmDualOsc"
VAR
long oscaddr
long astep
long bstep
long midevent
long midnote
long Voice
long Note[6]
long buttonstack[32]
PUB Main
DIRA[0..1] := %11
DIRA[2..3] := %00
OUTA[0..1] := %10 'start w/red loading light
debug.Start(115_200) 'start serial terminal cog
f.start 'start floating point cog
midi.start(2, doNoteOn+doNoteOff) 'start MIDI cog
osc.start(16)
waitcnt(4_000_000 + cnt)
'start oscillator cog
cognew(ButtonDebug, @buttonstack)
waitcnt(1_000_000 + cnt)
OUTA[0..1] := %01 'ready Green Light
debug.Str(STRING("16-bit Zynth all booted up"))
debug.NewLine
waitcnt(8_000_000 + cnt)
'-------------------------------------Start Note Loop-----------------------------
repeat
midevent := midi.evt
debug.Bin(midevent, 32)
debug.NewLine
midnote := midevent & $0000FF00
midevent &= $000000FF
midnote >>= 8
If midevent>0 'If velocity > 0 then noteon
'Find next free voice
if Voice == 1
Voice := 0
else
Voice := 1
'calculate note frequency and update note value
if (Voice == 0)
'step = 29527.90016 * 2^((note-69)/12)
astep := f.FRound(f.FMul(29527.90016, f.Pow(2.0, f.FDiv(f.FSub(f.FFloat(midnote), 69.0), 12.0))))
osc.seta(astep)
debug.Dec(midnote)
debug.Str(STRING(", "))
debug.Dec(astep)
debug.NewLine
elseif (Voice == 1)
bstep := f.FRound(f.FMul(29527.90016, f.Pow(2.0, f.FDiv(f.FSub(f.FFloat(midnote), 69.0), 12.0))))
osc.setb(bstep)
Note[Voice] := midnote
'else
' Voice := 0
' repeat while midnote<>Note[Voice] AND Voice<1
' Voice += 1
' Freq[Voice] := 0
' Note[Voice] := 0
' debug.NewLine
'fn = 2^(n/12)*440 Hz referenced from 440Hz where n = 69
PUB ButtonDebug | a , maxval
DIRA[3] := 0
DIRA[4] := 1
OUTA[4] := 0
a := 0
OUTA[4] := 1
waitcnt(10_000_000 + cnt)
maxval := 70_000_000
'1 ramp wave
'2 square
'3 triangle
'4 sine
repeat
if INA[3] == 1
if a<10
a += 1
else
if a>0
a -= 1
if a>9
OUTA[4] := 1
if (astep < maxval)
astep += 67
'bstep += 150
debug.Str(STRING("Inc"))
else
astep := 0
osc.seta(astep)
osc.setb(bstep)
debug.Str(STRING("Step:"))
debug.Dec(astep)
debug.Str(STRING(" ,"))
debug.Dec(bstep)
debug.NewLine
'debug.Str(STRING("Freq 1:"))
'debug.Dec(Freq[1])
'debug.NewLine
a := 0
else
OUTA[4] := 0
waitcnt(400000 + cnt)

Comments
mov Clktime, CNT waitcnt Clktime, Waittimeisn't getting you anywhere fast. waitcnt in PASM works differently from SPIN. It first waits for target (Clktime) then adds Waittime. In the above sequence at the time you reach waitcnt the system counter has advanced already and you have to wait for rollover. Also, your main loop doesn't have a time limit (may be intentional though). Make that a shr, shl picks up clkfreq (from long[0]).After disabling the waitcnt sequences, fixing Baddr and using counter mode LOGIC.always (instead of PLL, personal preference) I get some activity which looks reasonable. No further address issues whatsoever.
But when I add the debugger to your first code block and test it, all seems to be okay. I can step through the code and the registers are at the right places.
If you step thru the ASM init code you will find that the address for Baddr is set wrong. You do a SHL Baddr,#16 while it should be a SHR Baddr,#16 to get the right address.
Andy
Thanks for the quick responses these forums are great so is the chip and so are you two. If you live in london I'll bring you the beer as promised.
I'll soon be able to post the rest of my zynthesizer. I'm just now working on the analogue parts and implementing wavetable and sine.
Gawd bless, Milo