Shop OBEX P1 Docs P2 Docs Learn Events
Spin Help — Parallax Forums

Spin Help

Dave HeinDave Hein Posts: 6,347
edited 2010-01-15 18:13 in Propeller 1
I am trying to create an array of string pointers, but the address seem to be off by 16 bytes.· The following code works, but I have to add 16 to the string addresses for it to work.· If I set OFFSET to 0 it points to the wrong place in memory.· What am I doing wrong?

I also tried to use @strdata[noparse][[/noparse]5].· That doesn't work at all.· Why wouldn't that work?

CON
· _clkmode = xtal1 + pll16x
· _xinfreq = 5_000_000
OBJ
· sio : "FullDuplexSerial"
DAT
· strdata byte "ZERO", 0, "ONE", 0, "TWO", 0, "THREE", 0, "FOUR", 0, "FIVE", 0
· numstr long @strdata, @strdata + 5, @strdata + 9, @strdata + 13, @strdata + 19, @strdata + 24
· byte "END"
CON
· OFFSET = 16
PUB start | i
· sio.start(31, 30, 0, 57600)
· repeat i from 5 to 0
··· waitcnt(clkfreq + cnt)
··· sio.dec(i)
··· sio.tx(" ")
··· sio.str(numstr[noparse][[/noparse]i] + OFFSET)
··· sio.tx(13)

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2010-01-15 16:29
    The problem is that the compiler doesn't know the absolute address of strdata when it's compiling the constants, so the addresses are actually relative addresses, relative to the DAT block for the object being compiled (the main object in this case). This is always stored after the Spin parameter block which starts at hub location zero and occupies 16 bytes. The "@@" operator is intended to convert the relative address to an absolute address, so you'd write:

    sio.str(@@numstr[noparse][[/noparse] i ])

    Read the explanation on page 279 of the Propeller Manual.
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-01-15 16:30
    OK, I read the Spin document, and I understand now.· Addresses stored in the DAT section are relative addresses, and not abo(expletive)e addresses.· The "@@" operator has to be used to add the difference between the relative and absolute addresses.· The following code works OK.

    Dave

    CON
    · _clkmode = xtal1 + pll16x
    · _xinfreq = 5_000_000

    OBJ
    · sio : "FullDuplexSerial"

    DAT
    · strdata byte "ZERO", 0, "ONE", 0, "TWO", 0, "THREE", 0, "FOUR", 0, "FIVE", 0
    · numstr long @strdata, @strdata + 5, @strdata + 9, @strdata + 13, @strdata + 19, @strdata + 24
    · byte "END"

    PUB start | i, numstr1[noparse][[/noparse]5]
    · sio.start(31, 30, 0, 57600)

    · numstr1[noparse][[/noparse]0] := @strdata
    · numstr1[noparse][[/noparse]1] := @strdata + 5
    · numstr1[noparse][[/noparse]2] := @strdata + 9
    · numstr1[noparse][[/noparse]3] := @strdata + 13
    · numstr1[noparse][[/noparse]4] := @strdata + 19
    · numstr1[noparse][[/noparse]5] := @strdata + 24
    ·
    · repeat i from 5 to 0
    ··· waitcnt(clkfreq + cnt)
    ··· sio.dec(i)
    ··· sio.tx(" ")
    ··· sio.str(@@numstr[noparse][[/noparse]i])
    ··· sio.tx(" ")
    ··· sio.str(numstr1[noparse][[/noparse]i])
    ··· sio.tx(13)
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-01-15 16:36
    Interesting.· I mispelled "absolute" as "abo$lute" (substitute "s" for "$") in my previous email, and it got censored.nono.gif
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-01-15 16:37
    If your list of z-strings is fairly short you can create a routine that starts with the desired table and searches for a given target -- you do this by counting zeroes. The attached demo shows how this works.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-01-15 17:01
    I am working on a C-to-Spin converter, and this is going to make it a bit challenging.· The spin code in my example would have been generated by the following C statement:

    char *numstr[noparse]/noparse = {"ZERO", "ONE", "TWO", "THREE", "FOUR", "FIVE"};

    It's valid in C to assign a new pointer value to numstr, such as numstr[noparse][[/noparse]0] = "NIL", which would translate to numstr[noparse][[/noparse]0] = string("NIL").· In one case I would have to use @@ to reference numstr[noparse][[/noparse]0], and in the other case I would not use @@.

    I think for now I will just add an offset of 16 bytes to each entry of numstr.· This should work for top level object.· Ultimately, I'll probably need to add an offset to all predefined addresses at runtime during startup.

    Dave
  • Mike GreenMike Green Posts: 23,101
    edited 2010-01-15 17:09
    Since you know what declarations have initializers, you could generate initialization code that does the "numstr[noparse][[/noparse] x ] = @@numstr[noparse][[/noparse] x ]".
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-01-15 18:13
    Mike Green said...
    Since you know what declarations have initializers, you could generate initialization code that does the "numstr[noparse][[/noparse] x ] = @@numstr[noparse][[/noparse] x ]".
    The initialization code sounds like a good idea.· Another idea would be to generate a list of addresses that need to be fixed.· That would probably use less memory than using a spin statement for each address.

    Thanks,
    Dave
Sign In or Register to comment.