confusion with data types and accessing the data from memory
pidzero
Posts: 23
greetings,
Let's cosider this data block:
Let's cosider this data block:
DAT string_00 byte "Hello world. ", 0 valueA_01 byte $03 string_02 byte "This is ", 0 valueB_03 byte $2A string_04 byte "a test.", 0 { in reality, the data continues in this fashion for many lines }Instead of this:
PRI handle_string ( stringptr ) terminal.str ( stringptr ) PRI handle_valueA ( value ) ' this method expects a value from $00 to $FF repeat value beep PRI handle_valueB ( value ) ' this method expects a value from $00 to $FF repeat value blink PRI my_method handle_string ( @string_00 ) handle_valueA ( valueA_01 ) handle_string ( @string_02 ) handle_valueB ( valueB_03 ) handle_string ( @string_04 ) { in reality, my_method continues like this for many lines, in many different methods }i wanted to try something like this:
DAT process word $FF00, @string_00, $FF10, @valueA_01, { } $FF00, @string_02, $FF20, @valueB_03, { } $FF00, @string_04, $FFFF PRI my_method | pointer repeat until process[pointer]==$FFFF case process[pointer] $FF00 : handle_string ( process[pointer+1] ) $FF10 : handle_valueA ( {something here} ) $FF20 : handle_valueB ( {something here} ) pointer+=2I'm having some confusion about how to get a byte out of a memory location stored in an array of word sized data. I know this is a no-brainer, but I keep working in circles, never getting the data I expect. what goes in {something here}?
Comments
I'm happy to try C (a.k.a. learn C from zero C coding experience)... on the next project! It does seem like a worthwhile endeavor. However... this project is being developed for the Spinneret. Too bad the Spinneret's code resources are scarce... I've finally got a stable (and sexy, if i do say so myself) web server. I think porting the entire code base to C, not having any C experience yet, would be biting off more than I can chew... Seems SPIN will also be available on the Propeller 2. That's encouraging.
Can SPIN and C be used in a mixed fashion? (i.e. C top level with a few SPIN objects, or SPIN top level with a few C objects) Maybe a complete rewrite isn't necessary!
I believe you want byte[@@process[pointer+1]]. The Spin compiler doesn't link the code it produces - all pointers are relative to the beginning of the current object. When you use the @ operator in a PUB or PRI block, the compiler emits code that adds the object base to the offset at runtime, but when you use @ in a DAT block, it can't do it at runtime, so it does the best it can: it leaves the unlinked address there, which is usually not what you want. The @@ operator adds the current object base to an offset to get the final runtime pointer that you want.
I didn't fully understand the explanation, but I think I'll get it with some more hands on. It turns out the @@ was also necessary on the handle_string method; should read: handle_string ( @@process[pointer+1] )
So, here is the fully working implementation of this method:
One advantage to storing object offsets in the DAT sections is that it makes an object completely relocatable. This makes it easy to link compiled objects together. They just have to be concatenated, and only the object addresses in the method table need to be adjusted to complete the linkage. This also allows for relocating the entire linked binary in memory just by adjusting 5 values in the Spin header. The main drawback is that you have to adjust the addresses read from a DAT table using the @@ operator. In some of my Spin programs I use an initialization method to adjust the addresses once when the program first starts up.
BST and Homespun have added the @@@ operator that is used in the DAT section to produce absolute addresses. However, this is not supported in the Prop Tool or OpenSpin. For the top object you can generate absolute addresses by adding 16, such as @variable+16. I use the "+16" technique in the pfth Forth interpreter so that it can be compiled using the Prop Tool.