Shop Learn
converting coginit code to a call — Parallax Forums

converting coginit code to a call

I want to take some PASM code that's currently run via coginit and make it a function I call. What I don't understand is how to get data into ptra with a call. If I have for example:
cog := coginit(COGEXEC_NEW, @main, @abc)
How do I get the info from abc into call(@main)?

Comments

  • JonnyMacJonnyMac Posts: 8,057
    edited 2022-01-25 16:52

    The call() instruction only supports an address parameter so that's probably not going to work for you. Will an inline method work? You could do something like this:

    pub pasm_main(p_par) : result
    
      org
                    mov       ptra, p_par
                    {
                      rest of your pasm code here
                    }
      end
    
  • JonnyMacJonnyMac Posts: 8,057

    After reading the docs a bit more, it seems like you just have to add a second line: pass your address for ptra in an available register. I did this simple test:

    pub call_test() | ticks
    
      ticks := MS_001 * 100
    
      pinhigh(56)                                                   ' Eval LEDs off
      pinhigh(57)
      repeat
        call(@blip56)
        waitms(400)
    
        pr0 := @ticks                                               ' pass address via pr0
        call(@blip57)
        waitms(400)
    
    
    dat
                    orgh
    
    blip56          drvnot    #56
                    waitx     ##(MS_001 * 100)
      _ret_         drvnot    #56
    
    
    dat
                    orgh
    
    blip57          rdlong    pr0, pr0
                    drvnot    #57
                    waitx     pr0
      _ret_         drvnot    #57
    

    In your case, the first line of your pasm code would be:

            mov     ptra, pr0
    
  • DarkInsanePyroDarkInsanePyro Posts: 15
    edited 2022-01-25 17:17

    One of my libraries uses pre-loaded (via regload) PASM extensively and uses calls to execute assembly routines. There are 8 registers allocated that have symbols defined in both Spin2 and PASM so they can be shared. I use these registers to pass parameters.

    Example snippet from my library:

    PUB Read(ptr, size, timeout) : actsize | tocnt
    
    '' Reads data from the receive buffer, returning early if the timeout condition is met.
    ''
    '' Arguments
    ''   ptr      pointer to memory
    ''   size     amount of data to be read
    ''   timeout  time, in milliseconds, allowed to block for until returning
    ''            also accepts piCommon.TIME_IMMEDIATE and piCommon.TIME_INFINITE
    ''
    '' Returns:
    ''   number of bytes actually read
    
      PR0 := ptr
      PR1 := size
      PR2 := piCommon.TimeoutToCT(timeout)
      call(#read_asm)
      actsize := size - PR1
    

    Then in the PASM you can access the registers symbolically using PRx (PR0, PR1, etc.).

    Per the Spin2 documentation:

    $1D8..$1DF, which are general-purpose registers, named PR0..PR7, available to both PASM and Spin2 code.

    Pre-edit, looks like I was beat to the punch but figure I'd still submit it to say I vote in favor of what JonnyMac stated. It has been working out for me.

  • Either of those should work. I'll give them a try, thanks!

    Edit: Replied same time as DarkInsanePyro. That's great info as well.

Sign In or Register to comment.