Initializing asm pointers?
Peter Jakacki
Posts: 10,193
I just received my demoboard a couple of days ago and I have been busy modifying sample code etc.
What I want to do is to take microphone samples and store them in a buffer in main memory and playback from the oldest entry to achieve an audio delay.
Being very new at this the problem I am having at the moment is getting SPIN to pass the buffer address as a constant to init the assembly buffer pointer.
Just playing but I think that's right.
Can anyone give me a few pointers?
Thanks,
*Peter*
What I want to do is to take microphone samples and store them in a buffer in main memory and playback from the oldest entry to achieve an audio delay.
Being very new at this the problem I am having at the moment is getting SPIN to pass the buffer address as a constant to init the assembly buffer pointer.
Just playing but I think that's right.
Can anyone give me a few pointers?
Thanks,
*Peter*
CON sndsz = 4000 attenuation = 0 sndbufcon = sndbuf '!!!!!!!!!!!!! how do i pass the address of sndbuf to assembler? VAR word sndbuf[noparse][[/noparse]sndsz] DAT ' ' ' Assembly program ' org asm_entry mov dira,asm_dira 'make pins 8 (ADC) and 0 (DAC) outputs 'setup ADC movs ctra,#8 'POS W/FEEDBACK mode for CTRA movd ctra,#9 movi ctra,#%01001_000 mov frqa,#1 'setup DAC movs ctrb,#10 'DUTY DIFFERENTIAL mode for CTRB movd ctrb,#11 movi ctrb,#%00111_000 mov sndptr,sndptrvar mov asm_cnt,cnt 'prepare for WAITCNT loop add asm_cnt,asm_cycles :loop waitcnt asm_cnt,asm_cycles 'wait for next CNT value (timing is determinant after WAITCNT) mov asm_sample,phsa 'capture PHSA and get difference sub asm_sample,asm_old add asm_old,asm_sample 'delay buffer (Q&D) wrword @sndptr,asm_sample 'buffer the current sample add sndptr,#2 'bump ptr cmp sndptr,sndszvar 'end of buffer? if_ae mov sndptr,sndptrvar 'yep, reset ptr rdword asm_sample,@sndptr 'read oldest sample shl asm_sample,#32-bits-attenuation 'justify sample and output to FRQB mov frqb,asm_sample jmp #:loop 'wait for next sample period ' ' ' Data ' asm_cycles long |< bits - 1 'sample time asm_dira long $00000E00 'output mask asm_cnt res 1 asm_old res 1 asm_sample res 1 sndptr res 1 sndszvar long sndbufcon+sndsz sndptrvar long sndbufcon
Comments
cognew(@asm_entry, @sndbuf)
This will place the address of sndbuf[noparse][[/noparse]0] into the PAR register of the cog. To use the value (since·PAR is a read only register), copy it into sndptr with:
mov sndptr, par
You can also pass it by assigning sndptr via Spin before you run cognew, so you would do:
sndptr := @sndbuf
cognew(@asm_entry,0)
But in your case I would use the PAR method, this way you will keep a permanent read-only copy of the pointer to the buffer that you can reinitialize sndptr if needed.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.
Besides this I learned:
1. unlike the normal assembler words where the destination is to the left and source to the right instructions such as WRWORD must have the destination address on the right (doh!).
2. CMP instructions will happily compare but will keep it a secret unless you give them the WZ WC WR options (doh!)
I am sure I will say doh a few more times yet but this is what I have found. I have included the working code for anyone who is interested.
*Peter*
wr is the only default enabled affect flag and this is for instructions that inherently want to write a result, probing instructions such as TEST and CMP have no default affects, wz and wc must always be specified for any instruction you want those flags affected. This may seem crazy to people use to the Intel or Motorola instruction sets, but the conditional affect coupled with the conditional execution is very powerful in reducing code bloat. Notice there are no 'skip if...' instructions as there are in the SX, conditional execution makes them obsolete along with the memory location required for the instruction.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.
Don't forget about using 'nr' as well... this is a way that you can do a non standard comparison without affecting the destination register. For example...
The first line subtracts DataValueA from DataValueB ... If they are equal, then the Zero flag is set ...nr tells the compiler not to write the result back to DataValueA, so DataValueA and DataValueB remain intact.
The Second line branches to #DataEqual if the Zero flag has been set.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
Post Edited (Beau Schwabe (Parallax)) : 9/15/2006 5:57:27 PM GMT
I missed that point that Mike made and found out fairly quickly anyway. The compile/download/execute cycle is extremely short so it is nothing at all to make a slight change, even without saving and then hitting F10, it works brilliantly, well done!
The idea of learning and using Spin was not immediately entertained but because the propeller ide is dealing with objects in source code form it makes it very easy to use, investigate, debug, and adapt. There are many many projects I have NOW lined-up for the propeller, I know it's new but why hasn't it taken off faster than this? It is true that there are many that find it hard to change processors and tools (taught on XYZ n C n I'll die XYZ n C [noparse]:)[/noparse] ), but really that's their loss.
*Peter*
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.