Skip navigation
450 Views 4 Replies Latest reply: Jul 5, 2012 7:10 PM by mikekulesza RSS
mikekulesza Just Startin' 6 posts since
Jul 2, 2010
Currently Being Moderated

Apr 21, 2012 7:03 AM

Delay effect

Hi,

 

I'm trying to make a clean digital delay as a starting point for some other effects. To do this, I am trying to set up a circular buffer using modulo addressing. However, in the modulus (ie: m0, m1... m7) can have a max value of 32768, meaning I am limited to about 0.8 s of delay.

 

Does anyone know how to use the Address Generation Unit (AGU) with a larger modulo or perhaps stacking several modulo buffers or if there is another approach altogether? Any example code too would be great.

 

Thanks!

 

Mike

 

In the 56300 family manual, section 4 is about the Address Generation Unit (AGU) and 4.5.3 explains modulo addressing.

  • clangen Just Startin' 25 posts since
    Jul 8, 2009
    Currently Being Moderated
    Apr 24, 2012 1:00 PM (in response to mikekulesza)
    Re: Delay effect

    Hi Mike,

     

    the short answer is: yes, its possible. The long answer: its not that easy. You can't take benefit of the AGU directly since you cant't use the modifier registers for modulo adressing as you said since they are limited to 15-bit word length. I thought about that for a minute and got this simple idea:

     

    1.) Use linear adressing - set the modifier to $xxFFFF

    2.) You have to create your own modulo buffer. To do so you have to manage the pointer administration overhead by yourself - the classic approach.

    3.) You can use a single pointer (any Rx corresponding to the Mx modifier) and read an old sample before overwriting it by the actual one.

    4.) After each read/write procedure, increment the pointer and check if it has reached the end position (delay offset) for your delay buffer depth.

    5.) If so reset the pointer to the original address

     

    Here an idea for a code snippet (not tested)

     

    bufstart  equ $1000

    delay      equ $FFFF

    bufend    equ (bufstart + delay)

     

         org x;

    test     ds 1

     

         org p:

    ...

         ; initialization

         move #bufstart,r1

         move #$FFFFFF,m1

    ...

        ; this goes to loop

    ...

    ; get input value to x0

        move x:(r1),x1     ; read sample out of delay buffer

        move x0,x(r1)+    ; write input sample to delay line

     

    ; all the following is buffer management overhead - get your modulo addressing by hand.

        move #bufend,x1 ; get buffer end address

        move r1,a            ; get the current delay line address for test

        cmp  x1,a            ; see if pointer has reached the buffer end address - essentially the comparison (cmp) is a subtraction by x1 of a

        brpl   noreset       ; if not, do not reset pointer - check if the result is positiv (pl). If so don't reset the pointer.

                                    ; You may also try brnz (branch is not zero) to match the buffer end point more exactly

        move #bufstart,r1 ; if yes, set pointer to #bufstart

    noreset

    ...                              ; more code goes here

     

    Please give feedback if you could solve the problem. A good idea might be to check the code using the simulator. I will do so soon...

     

    Best regards

     

    Christian

  • clangen Just Startin' 25 posts since
    Jul 8, 2009
    Currently Being Moderated
    Apr 28, 2012 12:50 AM (in response to mikekulesza)
    Re: Delay effect

    Hi Mike,

     

    now I've checked my 'homebrewn' modulo and removed some bugs. The following code is to be tested by the simulator:

     

    ; Assembler directives

     

    bufstart  equ $1000

    delay     equ $000F

    bufend    equ bufstart+delay

     

         org p:$0                         ; Look for proper code memory base address on real silicon

     

    ; This code goes to initialization

     

         move #bufstart,r1             ; Here the pointer to the arbitrary length modulo buffer is placed.

                                                   ; The restrictive rules for modulo addressing are no longer valid...

         move #$FFFFFF,m1         ; ..since we use the linear addressing mode

     

    ; This code goes to main loop

    loop

     

    ; Get input value to x0 in advance - this code isn't listed here!

     

        move x:(r1),x1                    ; read sample out of delay buffer

        move x0,x:(r1)+                  ; write new input sample to delay line

     

    ; all the following is buffer management overhead - get your modulo addressing by hand.

    ; Anyway this isn't too much overhead compared to the strong modulo addressing rules! 

    ; We just check if the pointer r1 has reached the 'modulo' buffer end

    ; - if so, we just reset it to the original address location

     

        move #bufend,x1               ; get buffer end address

        move r1,a                          ; get the current delay line address for test if modulo buffer end is reached now

        cmp  x1,a                          ; see if pointer has reached the buffer end address

                                                  ; - essentially the comparison (cmp) is a subtraction by x1 of a

        jne  noreset                       ; if not, do not reset pointer - check if the result is not equal (ne).

                                                  ; If not so don't reset the pointer by jumping over the next instruction.

        move #bufstart,r1              ; if so, reset pointer to #bufstart

     

    noreset

     

        jmp    loop

    ; more code goes here

More Like This

  • Retrieving data ...

Bookmarked By (0)

Legend

  • Correct Answers - 5 points
  • Helpful Answers - 3 points