Shop OBEX P1 Docs P2 Docs Learn Events
PASM Memory Access — Parallax Forums

PASM Memory Access

RS_JimRS_Jim Posts: 1,768
edited 2009-09-08 20:34 in Propeller 1
I have a PSM routine running in one cog· I would like to use the results from another cog also running PSAM.
Specifically, I would like to access the JW_etimer output in a cog running PASM. I can access it in SPIN with a Longmove, how do I create the same access to the data from PASM?· As an extension How do I access global memory from PASM?
rs_jim

Comments

  • Cluso99Cluso99 Posts: 18,069
    edited 2009-09-07 19:14
    You access the hub using rdbyte/word/long and wrbyte/word/long. Best to look up the instructions in the manual. Note the source is always the hub in these instructions and the destination is the cog address. Indirect addressing is usually used, so to move a block, setup a counter and increment both pointers after each rd/wr then do a djnz back to the loop.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Links to other interesting threads:

    · Home of the MultiBladeProps: TriBlade,·RamBlade, RetroBlade,·TwinBlade,·SixBlade, website
    · Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
    · Prop Tools under Development or Completed (Index)
    · Emulators: Micros eg Altair, and Terminals eg VT100 (Index) ZiCog (Z80) , MoCog (6809)
    · Search the Propeller forums·(uses advanced Google search)
    My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
  • VIRANDVIRAND Posts: 656
    edited 2009-09-08 04:31
    It can be confusing that the rdbyte and wrbyte instructions must use another long in the cog RAM to specify the Hub RAM address, and it is that other long that is specified in the instruction, not the HubRAM address.
    It can also be confusing to figure out how to compile such longs with the right address in them.
    I recall trying a bunch of different ways of representing labels, which were different depending on whether
    the address was in the CON, VAR, or DAT sections. I don't think the manual clearly specifically explains that,
    and I often get stuck for a while when that comes up, trying to figure out how to access something in the Hub from a cog.

    Sometimes what finally works is kind of contrived, involving CON, VAR, DAT, and PAR values, and also @ symbols,
    so I WISH I had good examples of
    all the ways for cogs to access different things in the hub with the RDxxxx and WRxxxx instructions.
    I recall my last working try involved using the graphics.spin ONSCREEN_BUFFER as the address long value
    for two cogs to communicate through, resulting in weird pixel activity visible at the bottom of the screen.
    Due to the amount of time it took to find something that worked that day, I left it that way.

    If the Hub RAM address is less than 512 then it is easily and directly addressed in the rdbyte/wrbyte instructions,
    except it's not obvious what will be compiled into that small section of Hub RAM and if it is in danger of corruption.
  • RS_JimRS_Jim Posts: 1,768
    edited 2009-09-08 05:21
    If I write a memory address into a memory location that is part of an array that is accessable by a cog, ie

    long myvar
    and lets say that I write that address into myvar[noparse][[/noparse]0]
    when I read into my asm code
    mov temp,par
    rdlong local,temp 'if I then do a
    rdlong myval,local
    would I not be reading into myval the contents of the memory location stored at myvar[noparse][[/noparse]0]? My question is how to write The address of a variable from another cog into myval[noparse][[/noparse]0] I have two cogs operating independently of each other that need to share that value at the same time and it is created by a third cog.
    rs_jim
  • ericballericball Posts: 774
    edited 2009-09-08 20:02
    Let's back up for a moment.· To access HUB memory, your PASM code must "know" the address.· There are standard ways to provide this address to the PASM code:
    1. Set the value in SPIN before invoking COGNEW (i.e. HUBPTR := @hubvar ).· This is very easy to do, but there are some potential gotchas if you are starting multiple instances of the same PASM code with different values.
    2. Pass the address as the PAR parameter for COGNEW (i.e. COGNEW ( @cogstart, @hubvar ) ).· Again, this is easy but you're limitted to one long variable (or an array of longs).· But in this case it's trivial to have different values for each PASM instance.
    3. Pass the address of an array of longs where the elements are address pointers (i.e. parm[noparse][[/noparse]0] = @hubvar; COGNEW( @cogstart, @parm[noparse][[/noparse]0] ).· Of course, the array elements may contain more than just address pointers.· This also means you have to RDLONG the element to get the address.

    Now, with #3 the question is how to handle multiple PASM instances.· You could have an array for each instance, but that would be a waste of storage and mean you'd have to sync up any elements which need to be the same across instances.· A better way would be to use the COGID for each instance as a secondary index.· This would still use extra storage since you'd need to reserve 8 entries.

    The best way is to provide each instance with an index value - see my sprite driver for an example.· I embed the index value in the D register number of the first instruction (which is a JMP) just before invoking COGNEW.· This can then be extracted by the PASM code and used as needed.· It's safe because the value is copied to the COG before the next SPIN instruction is executed.



    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Composite NTSC sprite driver: Forum
    NTSC & PAL driver templates: ObEx Forum
    OnePinTVText driver: ObEx Forum
  • Ken PetersonKen Peterson Posts: 806
    edited 2009-09-08 20:13
    My favorite approach is to use Eric's #1 example. I usually set up a bunch of pointers in DAT and initialize them to point to my VAR values just before calling cognew. If I have another instance with different values, I just do the init step again before calling cognew again. It's a little more work for an init function to do up front, but it keeps the PASM code much simpler by keeping all the complexity in SPIN.
  • potatoheadpotatohead Posts: 10,261
    edited 2009-09-08 20:34
    I'll second that. That is very easy. One thing I like to do is put things into blocks. Read only in one block, shared in another, etc...

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Propeller Wiki: Share the coolness!
    Chat in real time with other Propellerheads on IRC #propeller @ freenode.net
    Safety Tip: Life is as good as YOU think it is!
Sign In or Register to comment.