Shop OBEX P1 Docs P2 Docs Learn Events
Need help with writing a byte of PASM data to the main ram — Parallax Forums

Need help with writing a byte of PASM data to the main ram

RavenkallenRavenkallen Posts: 1,057
edited 2010-08-29 19:23 in Propeller 1
So, after a long break i decided to jump back into learning assembly. Only problem i have run into so far is i have not figured out how to write/ read a byte of data to the hub ram. I have tried searching various places for the answer but i have not found anything good. I know somehow you have to pass the address of the cell of memory you are writing to, but i don't know how to do it...A brief piece of code or instructions on how to do this would be great....Thanks guys

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2010-08-26 15:07
    The main RAM is treated as a kind of I/O device by the cog. There are special instructions to read and write bytes, words, and long words (RDBYTE, RDWORD, RDLONG, WRBYTE, WRWORD, and WRLONG). In all cases, the destination address field has the cog address (0-511) of the long word to be used and the source address field has either an immediate hub address (limited to 0-511) or the cog address of a long containing the hub address. This hub address is always a byte address. If you're using xxWORD, the least significant bit is ignored. If you're using xxLONG, the least significant two bits are ignored. Note that the direction of the data transfer appears wrong for WRxxxx since the cog address is in the destination field and the hub address is in the source field, but that's the way it works.
  • RavenkallenRavenkallen Posts: 1,057
    edited 2010-08-26 15:48
    I must be doing something wrong. I still don't get it.
  • ratronicratronic Posts: 1,451
    edited 2010-08-26 16:05
    Ravenkallen - in the asm section you use 'par', look at this example.
    Con
      _clkmode = xtal1 + pll16x       
      _xinfreq = 5_000_000   
    Var
      long a
     
    Pub main 
      cognew(@entry,@a)
     
    Dat
                  org
    entry         rdlong    t1,     par   'store hub variable 'a' in cog variable 't1'
                  wrlong    t2,     par   'write cog variable 't2' to hub variable 'a'
    loop          jmp       #loop
    t1      res   1
    t2      res   1
    
  • Nick McClickNick McClick Posts: 1,003
    edited 2010-08-26 17:37
    I don't use PAR because I often want to pass several variables back and forth. this is what I do;
    var              
      long value1
      long value2
    
    PUB main
      value1ptr := @value1
      value2ptr := @value2
    
      cognew(@pasm, 0)  
      'Whatever additional spin stuff
    
    DAT
      ORG 0
      wrlong  dummyvar, value1ptr
      add  dummyvar, #100
      wrlong  dummyvar, value2ptr
    
    
      dummyvar                  long    100
      value1ptr                 long    0-0
      value2ptr                 long    0-0
    
  • RavenkallenRavenkallen Posts: 1,057
    edited 2010-08-26 19:33
    Thank you guys. I will try it out tomorrow. I gotta get some sleep tonight.
  • K2K2 Posts: 693
    edited 2010-08-26 20:17
    Ravenkallen, it's really easy: First, purchase a can of methylene chloride at your local paint supplier. By repeated application of this solvent to the Propeller case, followed by careful brushing with fine steel wool, you will eventually reach the silicon die. Be careful not to rub too hard or you will damage the fine circuitry.

    Next, obtain a fine pointed soldering iron and very thin wire. Carefully follow the circuit paths until you reach the row and column lines of the HUB RAM. Using as little solder as possible, tack a segment of fine wire to each line, and run these wires out to the external pins of the chip.

    Now, using simple OUTA, INA, and DIRA commands, experiment until you find the right combination of strobes to access the RAM locations you are interested in.

    Oh wait! You wanted ASM access to them! That can't be done. Sorry.
  • ke4pjwke4pjw Posts: 1,173
    edited 2010-08-27 08:29
    I don't use PAR because I often want to pass several variables back and forth. this is what I do;
    var              
      long value1
      long value2
    
    PUB main
      value1ptr := @value1
      value2ptr := @value2
    
      cognew(@pasm, 0)  
      'Whatever additional spin stuff
    
    DAT
      ORG 0
      wrlong  dummyvar, value1ptr
      add  dummyvar, #100
      wrlong  dummyvar, value2ptr
    
    
      dummyvar                  long    100
      value1ptr                 long    0-0
      value2ptr                 long    0-0
    

    I am glad you posted this Nick. That is the way I first learned to address spin variables, but didn't know if it was "proper" or not. I know it takes more memory in the cog addressing spin variables this way than just manipulating the PAR pointer. I guess if you got the longs to burn, it's OK.
  • potatoheadpotatohead Posts: 10,261
    edited 2010-08-27 09:14
    I like that method, if the SPIN and PASM are in the same program.

    Longs get burned either way, IMHO.

    One can also hard-code some addresses in the upper HUB RAM for communication too.

    The advantage of the PAR method comes when the PASM is going to be binary loaded. The cognew passes a single address, which the COG can then use to fetch, or operate on whatever HUB data it finds at that address.

    PASM can then be built, written out to SD, or the EEPROM, or something. Another program can fetch it, build up the data needed for it to operate, then cognew, leaving the PASM program to do it's thing in the COG.
  • K2K2 Posts: 693
    edited 2010-08-27 11:57
    Apologies for the levity... I only crack myself up, it would seem.

    In reality, its amazing how easily variables are passed between SPIN and ASM. It is an ongoing effort to recognize typical Propeller constructs at a glance; C has held my brain captive for several years.
  • jazzedjazzed Posts: 11,803
    edited 2010-08-27 12:29
    K2 wrote: »
    Apologies for the levity... I only crack myself up, it would seem.

    In reality, its amazing how easily variables are passed between SPIN and ASM. It is an ongoing effort to recognize typical Propeller constructs at a glance; C has held my brain captive for several years.
    Levity? It seemed a little deSilva-ish, although he was more concisely terse.
    You're not the only one who has found it hard to break out of C captivity :lol:
  • K2K2 Posts: 693
    edited 2010-08-27 13:45
    jazzed, thank you for the deSilva comparison, but I was actually referring to a much less terse comment (post #7) made earlier.
  • jazzedjazzed Posts: 11,803
    edited 2010-08-27 14:15
    K2 wrote: »
    jazzed, thank you for the deSilva comparison, but I was actually referring to a much less terse comment (post #7) made earlier.
    Yes, I wanted to comment on that one yesterday but it seemed more appropriate today somehow. I really enjoyed hearing someone else talk about C holding one captive. Still, I am not free :sad:

    Trying to be on topic now:

    My own style has evolved to one where I usually specify a table of longs and pass the base address via PAR to the COG. That way, I can have as many parameters as necessary for communicating with the COG with what I call "spinners". A "spinner" is a routine that waits for something to happen with a variable. A spinner variable is usually a command and/or response mailbox.

    --Steve
  • ericballericball Posts: 774
    edited 2010-08-28 10:13
    One caution regarding updating DAT variables is be aware that cognew does require time to copy the data from HUB RAM to COG RAM. So if you plan on invoking two instances of the cog program, don't change the variables without a delay between cognews.
  • RavenkallenRavenkallen Posts: 1,057
    edited 2010-08-28 10:30
    So i got it to work with the method described by Nick McClick....Thank you guys. I actually figured out the problem with my old test program. i forgot to use the name of the variable that held the value as the serial terminal output... This code works

    Con
    _clkmode = xtal1 + pll16x
    _xinfreq = 5_000_000
    Var
    long val1, val2
    obj

    serio: "parallax serial terminal"
    Pub main
    waitcnt(clkfreq + cnt)
    serio.startrxtx(31,30,0,250_000)
    value1ptr := @val1
    value2ptr := @val2
    cognew(@entry,0)
    repeat
    serio.dec(val1)
    serio.char(13)

    Dat
    entry
    ORG 0
    wrlong dummyvar, value1ptr
    add dummyvar, #100
    wrlong dummyvar, value2ptr


    dummyvar long 100
    value1ptr long 0-0
    value2ptr long 0-0
  • kuronekokuroneko Posts: 3,623
    edited 2010-08-29 19:06
    This code works ...
    Dat
    entry            
    ORG 0
      wrlong  dummyvar, value1ptr
      add  dummyvar, #100
      wrlong  dummyvar, value2ptr
    
      dummyvar                  long    100
      value1ptr                 long    0-0
      value2ptr                 long    0-0
    
    For how long?
  • RavenkallenRavenkallen Posts: 1,057
    edited 2010-08-29 19:09
    What do you mean?
  • kuronekokuroneko Posts: 3,623
    edited 2010-08-29 19:15
    What do you mean?

    Admittedly I don't know what exactly your PASM fragment is supposed to do but it's always bad style letting your program run into its data section. Either loop indefinitely or stop the cog. Not doing either may give you a headache later with more complicated code :)
  • RavenkallenRavenkallen Posts: 1,057
    edited 2010-08-29 19:23
    Oh, thank you. I did not know that( I guess it makes sense though). My example was very basic. The PASM section just wrote 2 bytes to the hub memory and the SPIN cog just repeated the value.....Yeah, it is all of those little things that add up to make your program impossible to debug.
Sign In or Register to comment.