********>this is where it goes [p120-121]
Chapter 5
Data
Unsigned integers
Unsigned integers can be used to store numbers that are within their range. They also provide a more reliable and memory-saving method of maintaining groups of yes/no flags to communicate between portions of your program.
If you want to maintain a group of yes/no flags in a small amount of space, you need to work at the bit level, and you need to be sure that the bit flags will stay the way you set them. You need certainty.
What you gain by using BYTEs, WORDs, and DOUBLE WORDs is certainty, so that you can depend upon the bits staying stuck on or off, the way you left them the last time.
If you tried to use signed integers for storing bits, an unexpected kind of data could make your number go negative, and then all of your bit flags would be reversed, backwards. Your whole system could crash.
While modern personal computers are generously endowed with cheap RAM memory, in comparison to earlier computers, there are still reasons to conserve use of memory. The most obvious one is to make your programs smaller, so that they load faster, take up less space on the disk drive and in RAM.
Byte (?)
Bytes are 8-bit (one-byte) unsigned integers with a range of 0 to 255.
PowerBASIC provides three different ways to define a variable as a byte unsigned integer: following the variable name with one question mark, using the DEFBYT statement, or using the BYTE keyword in a DIM statement.
Examples
Following the variable name VariableName? with one question mark
In a DEFtype statement DEFBYT VariableName
In a dimension statement DIM I AS BYTE
Remarks
Convenient for storage of small numbers.
Useful for maintaining a set of 8 yes/no flags.
See Figure 10.1, Data formats, on page 240.
Word (??)
Words are 16-bit (two-byte) unsigned integers with a range of 0 to 65535.
PowerBASIC provides three different ways to define a variable as a word unsigned integer: following the variable name with two question marks, with the DEFWRD statement, or using the WORD keyword in a DIM statement.
Examples
Following the variable name VariableName?? with two question marks
In a DEFtype statement DEFWRD VariableName
In a dimension statement DIM I AS WORD
Remarks
Use when an INTEGER is not large enough for your variable.
Use to indicate the offset address for PEEK and POKE.
Useful for maintaining a set of 16 yes/no flags.
See Figure 10.1, Data formats, on page 240.
Double Word (???)
Double words are 32-bit (four-byte) unsigned integers with a range of
0 to 4,294,967,295.
PowerBASIC provides three different ways to define a variable as a double word unsigned integer: following the variable name with three question marks, using the DEFDWD statement, or using the DWORD in a DIM statement.
Example
Following the variable name VariableName???
with three question marks
In a DEFtype statement DEFDWD VariableName
In a dimension statement DIM I AS DWORD
Remarks
Use when a LONG integer is not large enough for your variable.
Use to indicate absolute memory addresses for PEEK and POKE.
Useful for maintaining a set of 32 yes/no flags.
See Figure 10.1, Data formats, on page 240.
********>this is what it replaces [p150-151]
Bit level arithmetic statements
After you have defined your variables for use on a bit level, you will need to be able to check a single bit, to see if it is off or on, and you will need to be able to set and reset these bits, i.e., to turn them off or on, or to toggle them back and forth between off and on.
PowerBASIC numbers bits from right to left, starting with bit 0 as the rightmost bit.
To visualize this, see Figure 10.1, Data formats, on page 240.
The BIT function gives you a way to check whether a single bit is off or on.
The BIT statement gives you a way to turn the single bit on, or off, or to toggle it.
The SHIFT and ROTATE statements give you ability to do another assembly language trick, take a whole set of bits and shift or rotate their positions in storage.
Bit function
The BIT function gives you a quick way to check the status of any single bit, to see whether it is on or off.
DEFWRD Modemflags
%ReadyFlag=3
if BIT(Modemflags,%ReadyFlag)>0 then call SendMessage
Bit statement
The BIT statement gives you ways to change the status of any single bit, making it either on or off, or to toggle it between the two.
In toggling, if the bit was on, toggling it makes it go off. If it was off, toggling it makes it go on.
With SET and RESET, you are sure what the bit will be after your command.
With TOGGLE, you know that it is the opposite of the time before, that it flips back and forth.
%ReadyFlag=3
BIT SET Modemflags,%ReadyFlag
BIT RESET Modemflags,%ReadyFlag
BIT TOGGLE Modemflags,%ReadyFlag
Remarks
PowerBASIC does no error checking on arguments used in the BIT statement, for performance reasons, so you must be careful yourself that your arguments stay within the value range and width in bytes, or you may corrupt nearby variables or arrays.
Arithmetic shifting and rotating
The SHIFT and ROTATE statements give you ability to take a whole set of bits and shift or rotate their positions in storage.
Shifting the bits left one position multiplies the number by 2.
Shifting the bits right one position divides the number by 2.
A simple kind of loop is created by shifting the bits one to the left, and then testing for on or off in the leftmost position, with the BIT function or by testing whether the variable is positive or negative.
In this instance, you would want to copy the flag bits to a signed integer first, and then perform the loop.
The bits that you have dealt with are, in effect, deleted from the set of bits, and when you are thru, all the bits are cleared.
When you rotate the same set of bits, you preserve the bits that get shifted off of the end.
SHIFT STATEMENT
SHIFT RIGHT IntegerVariable??,Count
SHIFT LEFT IntegerVariable??,Count
Example
rem multiply by 2
SHIFT LEFT IntegerVariable??,1
rem check bit
for i%=1 to 16
SHIFT LEFT ModemFlags??,1
if BIT(ModemFlags??,1)>0 then call ServiceThisTask (i%)
next i%
rem check bit without shift
for i%=1 to 16
if BIT(ModemFlags??,i%)>0 then call ServiceThisTask (i%)
next i%
rem check bit by sign
ModemFlags%=ModemFlags??: ' loads a signed integer with flags
for i%=1 to 16
SHIFT LEFT ModemFlags%,1
if ModemFlags%<0 then call ServiceThisTask (i%)
next i%
ROTATE STATEMENT
ROTATE RIGHT IntegerVariable??,Count
ROTATE LEFT IntegerVariable??,Count
Example
rem multiply by 2
ROTATE LEFT IntegerVariable??,1
rem check bit
ModemFlags%=ModemFlags?? ' loads a signed integer with flags
for i%=1 to 16
ROTATE LEFT ModemFlags%,1
if BIT(ModemFlags%,1)>0 then call ServiceThisTask (i%)
next i%
Remarks
In this example, bits that are ON might be active tasks, while bits that are OFF might be disabled tasks, or tasks that have no work to do. The i% will remember task number.
BITS?, BITS??, BITS???, BITS%, BITS& functions
These functions return the least significant portion of a number in memory, ignoring the portion that holds the sign bit. This is useful when you convert between signed and unsigned formats, if you know that the number is positive.
See examples in the PowerBASIC Reference Guide.
**************************>this is where it goes [p153-154]
ISTRUE
The ISTRUE operator takes only one operand. If the operand is TRUE ( non-zero ), then this operator will return -1 as its TRUE value.
In other logical operators, any nonzero value means true.
rem false (busy) is zero
rem true (ready) is non-zero
SafeToUninstallFlag%=POPUP(1)
IF ISTRUE SafeToUninstallFlag% THEN
print"Uninstalling"
END
ELSE
print"Unable to uninstall"
END IF
ISFALSE
The ISFALSE operator takes only one operand. If the operand is FALSE ( non-zero ), then this operator will return the true logical negation as its TRUE value.
rem false (busy) is zero
rem true (ready) is non-zero
SafeToUninstallFlag%=POPUP(1)
IF ISFALSE SafeToUninstallFlag% THEN
print"Unable to uninstall"
ELSE
print"Uninstalling"
END
END IF