Shop OBEX P1 Docs P2 Docs Learn Events
Pointers in DAT space — Parallax Forums

Pointers in DAT space

BradCBradC Posts: 2,601
edited 2007-08-30 16:40 in Propeller 1
G'day all,
this one has me wondering.

If I declare a table in DAT space.. something like

DAT

crctable
word $0000, $0001, $0002





I can reference it from spin

somevar := @crctable
and that works fine


DAT

somevar    long    @crctable



does not if I reference it from within its cog in asm.. (see further down for a contrived example)

I end up having to declare a variable in spin, use somevar := @crctable and pass the address of somvar in my par block
then read it from assembler in the cog.


VAR
  long  somevar
PUB start
  somevar := @crctable
  coginit (@asmcode, @somevar)

DAT
asmcode   org
                rdlong  Pcrctable, par

Pcrctable  res  1





Most frustrating.. is there something I'm doing wrong? or do I have to pass pointers to all my globally declared data using the par blocks?

I'm doing a 16 bit crc in the cog asm code,
crc16byte     ' dc has the byte to add to the crc
              xor       dc, crc                 ' 3
              and       dc, #$FF                ' 4
              shl       dc, #1                  ' 5
              add       dc, Pcrcmask            ' 6
              rdword    db, dc                  ' 11.5
              shr       crc, #8                 ' 12.5
              xor       crc, db                 ' 13.5
crc16byte_ret ret                               ' 14.5





My problem is I have to pass "Pcrcmask" into the cog using spin, I just can't seem to get a pointer to the table at compile time in the DAT block....

The CRC table and the cog code are all in the same object, in the same DAT block. That, at least works...

Comments

  • KaioKaio Posts: 253
    edited 2007-08-30 10:55
    Brad,

    you have to use the following code to reference the table in your assembly code.
    DAT
    
    somevar    long    crctable
    
    


    But I don't know why it should be necessary. You can access the table also in your program.
               mov  tableptr,#crctable
    
    


    The @ operator is only used in spin to reference a memory address.
  • BradCBradC Posts: 2,601
    edited 2007-08-30 13:01
    Hmm, that won't work for me. I perhaps did not make myself as clear as I might have.

    The crc table is 256 words (128 longs) and resides in the HUB, not in the cog running the code. Thus I need to know the address of the table in HUB locations.

    I was somewhat hoping to be able to put that into the cog variables at compile time.

    Thanks for the thought though.
  • KaioKaio Posts: 253
    edited 2007-08-30 14:13
    Brad,

    sorry, this fact was not well known from your code snippets.
    But then you could use the following code.
    PUB start
      somevar := @crctable
      coginit (@asmcode, 0)
    
    DAT
    
    somevar    long    0
    
    


    You don't need a variable in spin. So the second argument on coginit is free for other use.
  • BradCBradC Posts: 2,601
    edited 2007-08-30 15:23
    Duh, now why didn't I think of that!

    Lovely! that should do it nicely.

    I'm already using a pretty big parameter block for passing large buffers back and forward, this way I don't have to make it even bigger.
  • deSilvadeSilva Posts: 2,967
    edited 2007-08-30 15:31
    I shall add this to the "Best Practices Section" in the tutorial. I did not not consider it neccesary - as being obvious - but I see the same questions and answers here week for week...
  • BradCBradC Posts: 2,601
    edited 2007-08-30 16:15
    I hadn't really thought it obvious. I was more struggling to understand why the compiler would do one thing when compiling spin, and something completely different when compiling the DAT area.

    What would be the use of @ in the DAT area? Or more accurately, what does it do?
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-08-30 16:30
    Brad, it has to do with scope. The only addresses which are automatically resolved for a assembly cog are those addresses which fall within it's own 496 long boundry. Since your reference DAT section is outside this area you must explicitly communicate it's location to the assembly code.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.

    Post Edited (Paul Baker (Parallax)) : 8/30/2007 4:57:17 PM GMT
  • deSilvadeSilva Posts: 2,967
    edited 2007-08-30 16:40
    Right, Brad, it is NOT obvious. But there are many components involved here...
    I just copy some lines I posted some days ago:
    There are four (!) sorts of @ in SPIN

    (-1) One is used to find the address-offset of a DAT-Variable as a constant. This is a little bit tricky. There is something like a "constant-context" during the SPIN compilation, where all constant expressions are evaluated; this happens most notably in the CON section, but also whenever the directive constant(&#8230[noparse];)[/noparse] is used in
    PUB/PRI, between the square brackets in the VAR section, and for all presets in the DAT section. (However these four situations are NOT ALWAYS handled equally by the compiler, e.g. DAT references can only be used in DAT itself and within constant(&#8230[noparse];)[/noparse]; and the names of I/O registers (which have a value between ($1f0 and $1ff) in DAT only. I think this is an unnecessary artificial restriction.)

    Notably for presetting DAT cells address-offsets are very handy (@datname), it can be added to them, or even differences can be stated (@end-@start or constant(@end-@start)); most other operations are more or less dangerous smile.gif

    However these are not (HUB-)addresses, but just some numbers (relative byte addresses to be precise) to be offset later! The reason is, that during the evaluation of constants the compiler is not yet in the situation to understand where the addressed variables will be allocated to!

    (-2) The second kind of @ is the address of DAT variables as such (@datname NOT in a constant context); this number is known by the compiler when generating the code.

    (-3) The third kind of @ is an address of VAR variables. Why is there a difference? Well you can instantiate more one object, which will lead to a multiplication of the VAR section, but there will be only ONE code section. Thus the poor code cannot know for which object it will have to work. This has to be computed from case to case dynamically!

    (-4) The fourth kind of @ is the address of a "local" variable (or a routine parameter). As SPIN routines can be called recursively this is an address in the stack, different from call to call, but independent of the object instantiation.

    (-5) What? Fifth? Well, there is a SPIN Operator called @@ …
    For the situation (1) - and for this situation only! - that address offset can be converted to a value corresponding to situation (2)

    Example:
    X := constant(@datvar)
    Y := @datvar
    Z := @@X

    Now : X < Y and Y == Z smile.gif
Sign In or Register to comment.