Shop OBEX P1 Docs P2 Docs Learn Events
How to get VAR block starting address for and object. — Parallax Forums

How to get VAR block starting address for and object.

KyeKye Posts: 2,200
edited 2011-01-02 08:13 in Propeller 1
So, I'm writing a SPIN object and like would like to be able to longfill the VAR section of the object really easily.

Right now I'm just using the address of the first element in the VAR block and longfilling from that. But I would rather have some address that references the whole VAR image instead...

Any easy way of doing this? I know what the size of the array is and that will remain constant.

Comments

  • Dave HeinDave Hein Posts: 6,347
    edited 2011-01-01 15:24
    The fifth word in a Spin binary file is the variable base address (vbase). The next word is the base address for stack variables (dbase). The size of the VAR space is dbase - vbase - 8. So if a binary image is loaded at the address "addr" the following code will clear the VAR section:
    vbase := word[addr][4]
    dbase := word[addr][5]
    numbytes := dbase - vbase - 8
    bytefill(vbase, 0, numbytes)
    
  • KyeKye Posts: 2,200
    edited 2011-01-01 16:54
    Yeah... but... I just want to clear the variable space of the object I'm wiritng the code for, not all variables for every object ;).
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-01-01 16:59
    Kye,

    Your first long variable is at the first address you'd clear. Your last byte variable is at the last address you'd clear.

    -Phil
  • KyeKye Posts: 2,200
    edited 2011-01-01 18:18
    Okay, So then how would I get... the "addr" part? I'm letting the SPIN compilier compile the object. I have no clue what the objects final base will be.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-01-01 19:50
    Kye,

    Here's an example:
    CON
    
       _clkmode       = xtal1 + pll16x
       _xinfreq       = 5_000_000
    
    VAR
    
      long  first_var[0]            'Put first.
      
      long  longa, longb, longc     'Anything can go here, in any order.
      word  worda, wordb[14]
      byte  bytea, byteb
      
      byte  last_var[0]             'Put last.
    
    PUB  Start
    
      bytefill(@first_var, 0, @last_var - @first_var)
    
    

    -Phil
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-01-01 20:06
    There are at least four ways to get the value of vbase. You can get the address of the first long, you can get if from the program header for the top object, you can read it from the stack frame or you can read it directly from cog address $1ec. The following program shows how this is done. There is some trickery involved in reading a cog address by overwriting the bytecode for "ina" with the bytecode for $1ec.
    con
      _clkmode = xtal1+pll16x
      _clkfreq = 80_000_000
      
    obj
      ser : "FullDuplexSerial"
    
    var
      long firstvar
    
    pub main
      ser.start(31, 30, 0, 115200)
      PrintVbase
    
    pub PrintVbase
      ' Print the address of the first VAR variable
      ser.str(string("@firstvar = "))
      ser.hex(@firstvar, 4)
      ser.tx(13)
      ' Print word 4 from the program header
      ser.str(string("word[0][4] = "))
      ser.hex(word[0][4], 4)
      ser.tx(13)
      ' Print the vbase in the call frame
      ser.str(string("word[@result][-3] = "))
      ser.hex(word[@result][-3], 4)
      ser.tx(13)
      ' Print the vbase from cog address $1ec in the Spin interpreter
      WriteVbaseRegAddr ' Overwrite the vbase register address in next instruction
      result := ina     ' Read vbase instead of ina
      ser.str(string("Cog address $1ec = "))
      ser.hex(result, 4)
      ser.tx(13)
    
    pub WriteVbaseRegAddr | retaddr
      retaddr := word[@result][-1]  ' Get return address
      byte[retaddr+1] := $8c        ' $1ec - vbase
    
  • KyeKye Posts: 2,200
    edited 2011-01-02 08:13
    Crazy!

    Thanks both of you!
Sign In or Register to comment.