Shop OBEX P1 Docs P2 Docs Learn Events
How do I place data at a specific HUB location ? — Parallax Forums

How do I place data at a specific HUB location ?

BeanBean Posts: 8,129
edited 2014-04-03 18:05 in Propeller 1
I tried
DAT
  ORG $7000
    LONG $5555_AAAA
But it says "Origin Exceed $1F0 limit"

Bean

Comments

  • msrobotsmsrobots Posts: 3,709
    edited 2014-04-02 17:22
    On P1 and spin you can't.

    except in code ... long[$7000] := $5555_AAAA

    ORG does just work for PASM and even there it will not do what you think it does.
    It will change the instruction coding as if the code is at ORG xxx. But will leave it where it is. So you have complete garbage.

    P2 SPIN/PASM has ORGH for HUB. possible doing what you think ORG does.

    Enjoy!

    Mike
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-04-02 18:46
    ORG sets the assembler's address pointer for the cog, nothing more. It has nothing to do with hub addresses. My recommendation is just:
    long[$7000] := $5555_aaaa

    But who knows what that might trample upon. What is your ultimate objective?

    -Phil
  • BeanBean Posts: 8,129
    edited 2014-04-03 04:26
    I have a large table that needs to be stored at a $1000 boundary for my code to work.

    Bean
  • kuronekokuroneko Posts: 3,623
    edited 2014-04-03 04:35
    Bean wrote: »
    I have a large table that needs to be stored at a $1000 boundary for my code to work.
    And there is no way your code would be happy with a 4n alignment?
  • BeanBean Posts: 8,129
    edited 2014-04-03 04:43
    I only have time for 2 instructions for the pointer to advance AND wrap from the end back to the beginning.

    So I am using...
    add pointer,#4
    and pointer,_HEX73FF
    ...
    _HEX73FF LONG $73FF
    

    When the pointer reaches $7400 the "and" instruction moves it back to $7000.

    Bean
  • kuronekokuroneko Posts: 3,623
    edited 2014-04-03 04:54
    Bean wrote: »
    I only have time for 2 instructions for the pointer to advance AND wrap from the end back to the beginning.
    Can you give more details (2 insns isn't much to go on)? The wrapping could potentially be limited to the size (which looks like po2) and the base address added on the fly. No promises though :)
  • ChrisGaddChrisGadd Posts: 310
    edited 2014-04-03 05:07
    Dunno how practical it is, but you could load your program into the EEPROM, then use a separate I2C object to write your table into the EEPROM starting at register $7000, then re-boot from EEPROM. Of course the table would have to be reloaded everytime the program was changed, but it should work.
  • lonesocklonesock Posts: 917
    edited 2014-04-03 10:18
    This doesn't answer the question, but may solve the problem.

    The prop uses only 16 bits for the address, ignoring the upper 16 bits. This lets you cheat by having an augmented address and delta address, i.e. an address where adding adr += del will wrap the number negative. Once the number is negative, a signed mins statement will restore the augmented pointer to the initial value. And all the rd/wr-long/word/byte commands will kindly ignore the upper 16 bits for you.

    Here is some test code in Spin:
    PUB test_address_wrap | lo, N, del, hi, vmin, vadd, v
    
      ' buffer address, length, step (would usually be 1, 2, or 4, but just testing a weird number)
      lo := 1765
      N := 61
      del := 3
      ' computed
      hi := lo + (N-1) * del
      
      ' hub addresses are 16 bits (32768 RAM, then 32768 ROM), and the upper 16 bits are ignored
      vadd := (1 << 16) | del
      'vmin := ((posx >> 16 << 16) - ((N-1)<<16)) | lo       ' easier to understand
      vmin := (((-1 >> 17) + 1 - N) << 16) | lo             ' easier to translate to PASM
      
    
      ' now test it
      start_serial_link
      v := vmin
      repeat
        waitcnt( clkfreq / 10 + cnt )
        term.tx( 13 )
        term.dec( lo )
        term.tx( " " )
        term.dec( v & 65535 )
        term.tx( " " )
        term.dec( hi )
        ' next point
        v += vadd
        v #>= vmin
    
        if v == vmin
          term.tx( 13 )
    
    So, all you need are 2 instructions: add, then mins.

    Jonathan
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-04-03 11:10
    Bean,

    It's inelegant and wasteful, but if you have the extra space, just create a DAT or VAR array that's 5120 ($1000 + $400) bytes long. Then you can dynamically redefine the beginning of the array as:
    array_addr := @array & $f000

    and be assured that there are still 1024 bytes in the array after that, inclusive.

    -Phil
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-04-03 12:38
    Bean, this code will insert extra zeroes to make the table aligned on a $1000 boundary.
    pub main
    
    dat
      label byte 0[(-16 - @label) & $fff]
      table byte "Hello World"
    

    EDIT: The "-16" is used to adjust for the object offset, so this technique will only work in the top object.
  • BeanBean Posts: 8,129
    edited 2014-04-03 15:18
    Thanks for all the ideas guys.
    I thought I was missing something because I could have sworn you could specify a HUB location, but I guess I was wrong.

    Thanks anyways,
    Bean
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-04-03 15:44
    Bean,

    Actually, a $800 alignment will work if you AND with $FBFF. So in my suggestion above, you'd be wasting a lot less RAM by making the size of the array $800 + $400 bytes long.

    -Phil
  • tonyp12tonyp12 Posts: 1,951
    edited 2014-04-03 17:23
    I would hardcode it in to a fixed location and that location would be: 2nd 1Kb block from the end as it allows you to clear bit10 and bit 0-9 counts from 0-1023 but bit 11 to 14 always stay set.

    Until the code reaches 30K in size I would Spin copy array to the upper locations (but the total Hub used will be 3Kb so pretty much similar to Phil above, unless you can find use for the upper 1Kb)
    When completely done programming could write the table to eeprom at this location as a final step, as the Prop will always read the full 32K of the eeprom

    So your pasm code will look like this
    rdlong mydata,pointer
    add pointer,#4
    and pointer,_7BFF

    pointer long $7800
    _7BFF long $7BFF
  • kuronekokuroneko Posts: 3,623
    edited 2014-04-03 18:05
    Since I asked the question, here is my offer. The principle is the same as used in TACHYON's PWM module. The wrapping is applied to the index (and/add, 0..1023), the base address is supplied by a LOGIC.always counter module (effective address is phsx + 2*frqx).
    org     _RUNMOD                   ' Compile for RUNMOD area in cog
    _PWM32          movi    ctrb, #%0_11111_000       ' LOGIC.always
                    mov     frqb, tos+1               ' table base address
                    shr     frqb, #1{/2}              ' divided by 2 (expected to be 4n)
                    mov     cnt, #5{14}+2*4+23        ' minimal entry delay
                    add     cnt, cnt
                    mov     phsb, #0                  ' preset (not optional, 8n)
    
    pwmlp32         [COLOR="#FFA500"]and     phsb, wrap32[/COLOR]              ' $0400 to $0000 transition        |
                    rdlong  X, phsb                   ' read from index + 2*table/2      | need to be back-to-back
    
                    waitcnt cnt, tos                  ' |
                    mov     outa, X                   ' update outputs
    
                    [COLOR="#FFA500"]add     phsb, #4[/COLOR]                  ' update read ptr                  |
                    rdlong  X, phsb                   ' read from index + 2*table/2      | need to be back-to-back
    
                    add     phsb, #4                  ' update read ptr
                    waitcnt cnt, tos                  ' |
                    mov     outa, X                   ' update outputs
    
                    jmp     #pwmlp32                     
    
    wrap32          long    256 * 4 -1
    
Sign In or Register to comment.