Pages

20 July 2010

GFA-BASIC 32 provides two unsigned integer data types, the Card and Byte data type. The Card is a 16-bits integer and allows you to store positive integral values in the range from 0 to 65535. The Byte is 8-bits data type allowing you store a positive value from 0 to 255.

It is not important how many positive numbers the data type can hold. More importantly is the way how these values are handled in case of mathematic operations. The default operation GFA-BASIC 32 allows on integers is signed arithmetic, because all other integer data types are signed types. However, when you include a value stored in a Card or Byte GFA-BASIC expands the value to an unsigned 32-bits integer before using it in a calculation. So, when you store 255 in a Byte, the value 255 is used in calculations.

Now, suppose you need to use a Byte to store values like: –1, 0, 1. (The GFA-BASIC 32 editor uses these values to store line indenting information and I used it to implement block folding.) You can simply store these values into a Byte and in case of –1 all bits of the byte are set resulting in $FF (=255).

Dim b As Byte = -1 ' b = 255 ($FF)

When the Byte is used in a calculation, the value 255 is applied, which is not what we want. We need the Byte to behave as a signed value; $FF must be interpreted as –1. For this to happen we must GFA-BASIC 32 tell to interpret the Byte as a signed byte explicitly using the Sbyte() function. The Sbyte(b) function forces a conversion to a signed expansion to 32-bits.

02 July 2010

A C-compiler treats arrays as pointers. An array-variable points to the first element. C computes the address of an array element by multiplying the element index with the size of the data type. This is automatic behavior of C. A pointer is an 32-bits integer holding an address pointing to a specific type. For instance, the next declaration defines a pointer to an array of 16-bit integers. To be effective it needs to be assigned an address first.

short* parr; parr = 0x0180980;

The variable parr references the Short (int16) at the given address. To read the value at the address:

short value; value = *parr;

Incrementing the pointer with one will let the pointer reference the next element, not the next memory location! E.g. parr++ will result in 0x0180982 (+2). Pointer arithmetic includes the size of data type.

parr++; value = *parr;

Accessing the fifth element in the array:

parr += 5; value = *parr; value = *(parr + 5) ; // even shorter

Almost the same can be simulated in GFA-BASIC 32 using the Pointer-type. Except GFA-BASIC does not use the size of the data type into pointer arithmetic. A Pointer variable defines the type of the variable without an address, like C.

Local parr As Register Pointer Short
Pointer(parr) = 0x0180980
Local Short value value = parr

To obtain the value from the address GFA-BASIC 32 doesn't provide an indirection operator as C does, as in value = *parr. In GFA-BASIC 32 you must first assign the pointer variable an address using Pointer(parr)= addr. Once the pointer variable is assigned an address, it can be used as a normal variable. Note that Pointer()= performs an kind of implicit VarPtr(parr) =addr, because a pointer variables VarPtr == Null.
Incrementing the pointer to point to the next element requires to set the variable's VarPtr to the next address, in this case plus 2 (SizeOf(Short)==2). So, first give the variable a new address and than access the address using normal variable syntax.

Pointer(parr) = Pointer(parr) + SizeOf(parr)
value = parr

The next sample shows how to iterate over a C- array and how to access an element by index.