Well, all SUBs and FUNCTIONs discussed so far are supposed for any special
case memory operations. Now we still need a set of routines for the low
level access to the memory. That is, accessing single bytes, words etc..
Here the various PokeXX and PeekXX routines come into place. The "XX" in
the SUB/FUNCTION names are replaced by letters logically representing the
size/type of an access. The routines defined so far are:
Integers:
PokeB / PeekB%% - byte access (8 bits)
PokeW / PeekW% - word (in QB64 INTEGER) access (16 bits)
PokeL / PeekL& - long access (32 bits)
PokeLL / PeekLL&& - long long (in QB64 _INTEGER64) access (64 bits)
Floating points:
PokeS / PeekS! - write/read single floating point (32 bits)
PokeD / PeekD# - write/read double floating point (64 bits)
Strings:
PokeSTR / PeekSTR$ - write/read zero terminated strings
The general syntax for all PokeXX SUBs and PeekXX FUNCTIONs is:
PokeXX addr&, offs&, value
value = PeekXX(addr&, offs&)
The addr& and offs& arguments are generally interchangeable, they are
simply added together internally to build the actual address to access.
I chose this way, so you can put the base address (eg. any structure)
into the addr& argument and the offset to access within that structure
to the offs& argument. However, you can also add the addresses and
offsets yourself and put it in either addr& or offs& and set the unused
argument to zero. Simply find the most convenient way for you.
Note that the integer PokeXX routines can take either signed or unsigned
values, but the respective PeekXX functions will always return signed
values. However, if the result is assigned to a unsigned integer variable,
then the value is automatically converted to unsigned again. If needed
within a temporary operation, then you may use a logic AND operation of
the appropriate size to convert the value. See example:
'CHR$ accepts positive values only, so if in doubt what is returned
'by PeekB%%, then make the result unsigned for CHR$ to avoid errors
PRINT CHR$(PeekB%%(addr&, offs&) AND &HFF~%%)
Something special you need to keep in mind using PokeSTR is, that this SUB
does automatically add the zero termination byte after the actual string.
That is, you don't need to add CHR$(0) to any of your strings, but on the
other hand it will be required to allocate buffers with LEN(string) + 1,
or the adding of the zero byte would violate innocent memory following the
buffer. If you define embedded strings within a structure using the SUB
DefSTRING from the types.bm include file, then this SUB already takes care
of adding 1 for the termination byte, also the FUNCTION CreateGPMString&
discussed earlier will take care of allocating a big enough buffer. You
just need to remember the +1 rule, if you for any reason allocate a buffer
by yourself.
On the other hand PeekSTR$ will always return the string without the zero
termination byte, hence you get it back as you did poke it in. So in fact
you can also poke and peek back empty ("") strings.
Back to GPM Functions