View Full Version : byte/word/long boundarys ?
01-30-2007, 10:17 AM
Suppose I define a table in a DAT area thusly:
Head byte 0
Tail byte 0
Buf long 0
If I then pass a pointer to the table ( i.e. @Head ), to a new method as HeadPtr, I envision getting bit (if not careful) by boundarys.
I can read Head & Tail like this:
H := byte [HeadPtr]
T := byte [HeadPtr]
But since the rest of the table is Longs, I'll speculate that there are 2 bytes unused between Tail and the beginning of the Longs(?)
To access the first Long in the table it seems that I would use:
N := long [HeadPtr]
Am I getting it?
01-30-2007, 10:33 AM
Yes, the compiler will guarantee that Buf is indeed on a long word boundary by adding 2 bytes between Tail and Buf. To access the first long in Buf, do "long[HeadPtr+4]" since the first long (index zero) consists of Head/Tail/padding. To access the k'th long (zero relative) do "long[HeadPtr+4][k]".
01-30-2007, 10:44 AM
Also, if it happens that the argument that is not a multiple of 4, the compiler will round down to the nearest multiple of 4.
will round down to
and for absolute addresses,
word[$E001] ' in the HUB rom, sine table
will round down to
01-30-2007, 10:52 AM
"Yes, the compiler will guarantee that Buf is indeed on a long word boundary by adding 2 bytes between Tail and Buf. To access the first long in Buf, do "long[HeadPtr+4]" since the first long (index zero) consists of Head/Tail/padding. To access the k'th long (zero relative) do "long[HeadPtr+4][k]".
I was waiting for a correction to the above, but I guess it isn't coming ;=)
HeadPtr points to an absolute address, regardless of byte/word/long (?)
Buf starts 1 Long = 4 bytes offset from HeadPtr.
So I would think that the first Long entry in Buf would be long [HeadPtr]
Since this statement is only dealing in Longs, I would think that HeadPtr+4 would take me 4 Longs past HeadPtr.
01-30-2007, 11:14 AM
The square brackets that follow BYTE/WORD/LONG are not quite subscript brackets. The LONG syntax treats the value in the brackets as a byte address. I think Tracy is wrong in that the compiler doesn't look at the value at all. It just generates code to compute it. I know (from Chip) that the RDLONG/WRLONG instructions ignore the lower two bits of Hub address given which effectively rounds down to the nearest long word boundary. The RDWORD/WRWORD instructions similarly ignore the lower bit of the Hub address given which effectively rounds down to the nearest word boundary.
If you give a second set of square brackets after the BYTE/WORD/LONG, the value given is a true subscript. You could write "LONG[HeadPtr][ 1]" to access the 2nd long word in the work area which would be the first long word in Buf.
I hope this has cleared things up a little.
Post Edited (Mike Green) : 1/30/2007 6:55:02 PM GMT
01-31-2007, 01:31 AM
Correct. The computations are as follows:
byte[ a ] -> accesses byte at address a
word[ a ] -> accesses word at address (a & ~1)
long[ a ] -> accesses long at address (a & ~3)
byte[ a ][ b ] -> accesses byte at address a + b
word[ a ][ b ] -> accesses word at address (a & ~1) + 2 * b
long[ a ][ b ] -> accesses long at address (a & ~3) + 4 * b
You can also use the @ operator (although this won't truncate bits) so if you want to
c := a + 4 * b (7 bytes of spin)
a "faster" way to do it might be
c := @long[ a ][ b ] (4 bytes of spin)
Of course you must really be desparate for space in order to perform such obfuscation.