Pointers in DAT space
BradC
Posts: 2,601
G'day all,
this one has me wondering.
If I declare a table in DAT space.. something like
I can reference it from spin
somevar := @crctable
and that works fine
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.
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,
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...
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
you have to use the following code to reference the table in your assembly code.
But I don't know why it should be necessary. You can access the table also in your program.
The @ operator is only used in spin to reference a memory address.
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.
sorry, this fact was not well known from your code snippets.
But then you could use the following code.
You don't need a variable in spin. So the second argument on coginit is free for other use.
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.
What would be the use of @ in the DAT area? Or more accurately, what does it do?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.
Post Edited (Paul Baker (Parallax)) : 8/30/2007 4:57:17 PM GMT
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(…[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(…[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
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