Shop OBEX P1 Docs P2 Docs Learn Events
start spin function from asm routine — Parallax Forums

start spin function from asm routine

dany73dany73 Posts: 2
edited 2007-12-19 21:00 in Propeller 1
I have asm routine running on cog1, all other the cogs are stopped. I would like start spin interpreter on cog0 from my routine on cog1, without resetting·the propeller. How can I do this? I suppose I have to load interpreter from ROM...
Thanks a lot

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2007-12-19 14:43
    Here is some code posted by Chip quite a while ago.
    It's part of FemtoBasic and the Propeller OS and is
    used as part of the "load a new program from EEPROM
    or an SD card" routine.
    ' Start up oscillator and begin Spin program at $0010
    ' (assumes EEPROM data already loaded into $0000-$7FFF)
    ' (assumes currently running RCFAST oscillator)
    ' (assumes this is COG 0 - gets rebooted)
    '
                  rdbyte  address,#$0004          'if xtal/pll enabled, start up now
                  and      address,#$F8             '..while remaining in rcfast mode
                  clkset  address
    :delay     djnz     time_xtal,#:delay       'allow 20ms @20MHz for xtal/pll to settle
                  rdbyte  address,#$0004           'switch to selected clock
                  clkset  address
                  coginit interpreter              'reboot cog with interpreter
    
    time_xtal       long    20 * 20000 / 4 / 1      '20ms (@20MHz, 1 inst/loop)
    interpreter     long    $0001 << 18 + $3C01 << 4 + %0000
    address          res     1
    
    
  • Fred HawkinsFred Hawkins Posts: 997
    edited 2007-12-19 14:44
    It's been, as far as I know, nodded at but it's still a NYRS -- Not Yet Revealed Secret. The most recent mention that I recall was along the lines of possible but difficult (to explain|do).

    Opinion overturned·by one longer in the tooth.
  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-12-19 16:41
    Mike Green said...

                      coginit interpreter              'reboot cog with interpreter
    ...
    interpreter     long    $0001 << 18 + $3C01 << 4 + %0000
    
    


    That's interesting. So the interpreter is started with PAR set to $0004 and the cog code loaded from $F004.

    So what's happening with the clock setting part of the code? What's that all about?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Help to build the Propeller wiki - propeller.wikispaces.com
    Play Defender - Propeller version of the classic game
    Prop Room Robotics - my web store for Roomba spare parts in the UK
  • Mike GreenMike Green Posts: 23,101
    edited 2007-12-19 16:56
    Read the comments in the code. It takes a while for the external crystal oscillator to stabilize, then for the PLL to stabilize before you can actually use the new clock.

    The first 16 bytes of memory contain a variety of information used by the interpreter and the running Spin program itself. It's possible to place the Spin program elsewhere in memory and start up a Spin interpreter with a different "control block". The compiler has no documented provision for compiling such a program.
  • RaymanRayman Posts: 14,162
    edited 2007-12-19 17:02
    So, I guess:
    The first 16 bytes of memory contain a variety of information used by the interpreter and the running Spin program itself...
    is the: NYRS -- Not Yet Revealed Secret
  • Mike GreenMike Green Posts: 23,101
    edited 2007-12-19 17:07
    This is clearly documented in a description of the boot process. Have a look through Graham Stabler's Good Thread Index in the "sticky thread" section of the forum. There's a lot of stuff that has been documented, just not cross referenced and easily indexed.

    Assembling and indexing all this detail is very time-consuming and resource-intensive. I'm sure it will happen eventually, but it may take several years. Consider how much stuff is available regarding Stamp programming and how long the Stamp (BS2) has been available.

    Post Edited (Mike Green) : 12/19/2007 5:12:56 PM GMT
  • RaymanRayman Posts: 14,162
    edited 2007-12-19 17:12
    Mike:
    Do you know of the same 16 bytes would be common to all SPIN functions in the same program? I.e., if you were to start a SPIN function from the main SPIN object, would it get the same 16 bytes as the main object did when it started?

    Wait a minute...· Since you can launch any SPIN function in a new cog, does this mean all function have 16 bytes stored before them?
  • deSilvadeSilva Posts: 2,967
    edited 2007-12-19 17:35
    No, the 16 bytes talked about are the very first 16 bytes of the HUB. It is unclear whether they can be offset or not...
  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-12-19 17:51
    Mike Green said...
    Read the comments in the code. It takes a while for the external crystal oscillator to stabilize, then for the PLL to stabilize before you can actually use the new clock.

    Mike, of course I read the comments in the code. It still didn't make sense to me. Clocks and PLLs are not things I've ever needed to get involved with.

    I think I've got it now through reading around and thinking it through a bit more.

    1) A Spin binary specified the CLK register that needs to be used at location $0004. e.g. Standard for Hydra is $6E
    2) RCFAST lets the Prop function at about 12MHz without a crystal. So it's set to do that whilst the crystal and PLL are set up to match the settings required by the Spin Binary.
    3) After a wait for the crystal and PLL to stabilise, the PLL multiplier is set as required by the Spin binary.

    Yes, that's what the comments say, it was the particular bits of the CLK register and RCFAST etc. that I wasn't familiar with.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Help to build the Propeller wiki - propeller.wikispaces.com
    Play Defender - Propeller version of the classic game
    Prop Room Robotics - my web store for Roomba spare parts in the UK
  • Mike GreenMike Green Posts: 23,101
    edited 2007-12-19 17:55
    Rayman,
    The 16 bytes are the prefix of the Spin PROGRAM. You should really read the information that was put together by Cliff Biffle, Gear, and others. As I said, there's very little about the format of Spin programs that's not already known publicly.

    deSilva,
    The 16 bytes can be offset, but, without a compiler that can generate code that way, it's not very useful. It would be possible for a program to go through a Spin binary program and relocate everything prior to initiating a new copy of the interpreter. I had looked into that in the past as a way to do Spin overlays, but never got to actually doing it.

    CardboardGuru,
    Yeah, there's a huge amount of detail that you have to be at least a little familiar with if you want to get fancy with the Propeller. It's nice that you don't have to know it all to do most of what you might want to accomplish. The same process is similar with really any microcontroller. At some point, you have to get "down and dirty" with the grubby details of bits and bytes and control registers and what those "blocks" on the block diagram really do. The "errata" for some of the PICs are real gems ... what you have to understand to do some of the "workarounds" is amazing.

    Post Edited (Mike Green) : 12/19/2007 6:03:02 PM GMT
  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-12-19 18:03
    Ale, Desilva,

    The 16 bytes are always in the first 16 bytes of memory. They are information about the program as a whole, and are not relocatable or per object. There's a pointer at $0006 that points to the start of the top object. Proptool always that this pointer at $0006 pointing to $0010, but presumably that could be anywhere. Then each other object is pointed to from whichever object includes it.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Help to build the Propeller wiki - propeller.wikispaces.com
    Play Defender - Propeller version of the classic game
    Prop Room Robotics - my web store for Roomba spare parts in the UK
  • Fred HawkinsFred Hawkins Posts: 997
    edited 2007-12-19 18:22
    Context: I think this is the thread where Chip released that code: http://forums.parallax.com/showthread.php?p=596171

    ·
  • dany73dany73 Posts: 2
    edited 2007-12-19 18:24
    thanks a lot for your help!
  • RaymanRayman Posts: 14,162
    edited 2007-12-19 18:44
    Ok, one last thing... How does it know where to go for stack space?
  • Mike GreenMike Green Posts: 23,101
    edited 2007-12-19 19:29
    The interpreter gets all that sort of information (like the initial stack pointer) from the 16 byte header during its initialization. This information is copied into the new cog by the interpreter's initialization routine and then isn't needed further.
  • RaymanRayman Posts: 14,162
    edited 2007-12-19 19:53
    Mike: Thanks. Is this information still used when a cog is rebooted/reloaded in the method you described above? I seems to me that if it doesn't get the clock freq., it probably doesn't get the stack info either (but, maybe you know better?).
  • hippyhippy Posts: 1,981
    edited 2007-12-19 21:00
    A quick bit of hackery ...

    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
    OBJ
      tv : "TV_Text"
    
    PUB Main
      word[noparse][[/noparse] $000C ] := AtBootable ' := @Bootable
      cognew(@Booter,0)
    
    PRI Bootable
      tv.Start(12)
      repeat
        tv.out($01)
        tv.str(String("It's Alive !",$0D))
        
    PRI AtBootable
      result := $003C
      
    DAT
    
    Booter        coginit   BootIt
    BooterEnd     jmp       #BooterEnd
    
    BootIt        long      $0004 << 16 | $F004 << 2 | %1000
    
    
    



    Propeller boots, PUB Main runs. That pokes the address of PRI Bootable into the info block, launches a Cog which causes another Cog to load with the Spin Interpreter using the original info block but now set to run PRI Bootable instead of PUB Main.

    This is a real hack because the second Spin Interpreter ( running PRI Bootable ) re-uses and overwrites the stack space PUB Main was using. In this case, PUB Main has terminated by the time PRI Bootable is up and running so no conflict of use. To do this properly, PRI Bootable should be given its own stack space to work with, which requires updating other entries in the info block.

    PRI AtBootable is a hack because there are no function pointers, so no way to do ":= @Bootable". Address determined using my bytecode decompiler.

    We wouldn't need the PASM code at all if the Propeller supported "cognew(@$F004,$0004)" but that won't compile, and at least this way it's clearer to see PASM is launching a Spin method.

    Added : Independent stack spaces ... roll.gif

    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
    OBJ
      tv : "TV_Text"
    
    VAR
      long counter
      long stack[noparse][[/noparse]1000]
    
    PUB Main
      word[noparse][[/noparse] $000C ] := AtBootable ' := @Bootable
      word[noparse][[/noparse] $000A ] := @Stack
      word[noparse][[/noparse] $000E ] := @Stack+4
      cognew(@Booter,0)
      repeat
        counter++
        
    PRI Bootable
      tv.Start(12)
      repeat
        tv.out($01)
        tv.str(String("It's Alive !",$0D))
        tv.dec( counter )
        
    PRI AtBootable
      result := $004B
      
    DAT
    
    Booter        coginit   BootIt
    BooterEnd     jmp       #BooterEnd
    
    BootIt        long      $0004 << 16 | $F004 << 2 | %1000
    
    
    



    And, finally, relocated information block. I moved it to $7F00-$7F0F simply because that was easy to do ...

    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
    OBJ
      tv : "TV_Text"
    
    VAR
      long counter
      long stack[noparse][[/noparse]1000]
    
    PUB Main
      bytemove($7F00,$0000,16)
      word[noparse][[/noparse] $7F0C ] := AtBootable ' := @Bootable
      word[noparse][[/noparse] $7F0A ] := @Stack
      word[noparse][[/noparse] $7F0E ] := @Stack+4
      cognew(@Booter,0)
      repeat
        counter++
        
    PRI Bootable
      tv.Start(12)
      repeat
        tv.out($01)
        tv.str(String("It's Alive !",$0D))
        tv.dec( counter )
        
    PRI AtBootable
      result := $0055
      
    DAT
    
    Booter        coginit   BootIt
    BooterEnd     jmp       #BooterEnd
    
    BootIt        long      $7F04 << 16 | $F004 << 2 | %1000
    
    
    

    Post Edited (hippy) : 12/19/2007 9:45:01 PM GMT
Sign In or Register to comment.